@vscode/markdown-editor 0.0.2-4 → 0.0.2-40
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/_observables/observableInternal/index.d.ts +1 -1
- package/dist/_observables/observableInternal/logging/consoleObservableLogger.d.ts +1 -1
- package/dist/_observables/observableInternal/logging/debugger/devToolsLogger.d.ts +1 -1
- package/dist/_observables/observableInternal/logging/logging.d.ts +1 -1
- package/dist/_observables/observableInternal/reactions/{autorun.d.ts → createEffect.d.ts} +11 -3
- package/dist/config-Dvgk17FF.js +282 -0
- package/dist/config-Dvgk17FF.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +1138 -56
- package/dist/index.js +4405 -1877
- package/dist/index.js.map +1 -1
- package/dist/markdown-editor.css +1 -0
- package/dist/observables.js +45 -43
- package/dist/observables.js.map +1 -1
- package/dist/{runOnChange-C00UIwqQ.js → runOnChange-e7FtCqOQ.js} +115 -111
- package/dist/runOnChange-e7FtCqOQ.js.map +1 -0
- package/dist/stringEdit-CVDbCUBY.js +215 -0
- package/dist/stringEdit-CVDbCUBY.js.map +1 -0
- package/dist/web-editors.d.ts +130 -0
- package/dist/web-editors.js +5169 -0
- package/dist/web-editors.js.map +1 -0
- package/package.json +46 -9
- package/src/contrib/comments/commentInput.css +150 -0
- package/src/contrib/comments/comments.css +129 -0
- package/src/contrib/commentsVscode/vscodeCommentWidgetV2.css +171 -0
- package/src/view/editor.css +495 -21
- package/src/view/themes/default.css +11 -3
- package/src/view/themes/github.css +12 -8
- package/src/view/themes/vscode-default.css +359 -0
- package/src/view/themes/vscode-github.css +356 -0
- package/dist/runOnChange-C00UIwqQ.js.map +0 -1
- /package/dist/_observables/observableInternal/reactions/{autorunImpl.d.ts → createEffectImpl.d.ts} +0 -0
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
|
-
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;
|
|
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;
|
|
@@ -71,7 +88,7 @@ export declare class AsyncClipboardStrategy implements IClipboardStrategy {
|
|
|
71
88
|
connect(context: IClipboardContext): IDisposable;
|
|
72
89
|
}
|
|
73
90
|
|
|
74
|
-
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;
|
|
75
92
|
|
|
76
93
|
/**
|
|
77
94
|
* A block-level node. Every block may carry a {@link leadingTrivia} glue — the
|
|
@@ -92,7 +109,7 @@ declare abstract class BlockAstNodeBase extends AstNode {
|
|
|
92
109
|
/**
|
|
93
110
|
* One block's place in the rendered document.
|
|
94
111
|
*
|
|
95
|
-
*
|
|
112
|
+
* Geometry is in editor-local CSS pixels. `height` is either a real DOM measurement
|
|
96
113
|
* (`isMeasured: true`) or an estimate produced when the block is not
|
|
97
114
|
* currently mounted (`isMeasured: false`). Estimates exist so virtual
|
|
98
115
|
* rendering can size the scroll container without mounting every block.
|
|
@@ -107,6 +124,13 @@ export declare interface BlockMeasurement {
|
|
|
107
124
|
readonly block: BlockAstNode;
|
|
108
125
|
readonly absoluteStart: number;
|
|
109
126
|
readonly height: number;
|
|
127
|
+
/** Local border box when mounted and measured. */
|
|
128
|
+
readonly rect: Rect2D | undefined;
|
|
129
|
+
/** Local horizontal padding-box clip when this block scrolls horizontally. */
|
|
130
|
+
readonly viewportClip: {
|
|
131
|
+
readonly left: number;
|
|
132
|
+
readonly right: number;
|
|
133
|
+
} | undefined;
|
|
110
134
|
readonly isMeasured: boolean;
|
|
111
135
|
readonly visualLineMap: VisualLineMap | undefined;
|
|
112
136
|
readonly viewNode: ViewNode | undefined;
|
|
@@ -130,7 +154,7 @@ declare class BlockQuoteViewData {
|
|
|
130
154
|
constructor(ast: BlockQuoteAstNode, content: readonly AnyViewData[]);
|
|
131
155
|
}
|
|
132
156
|
|
|
133
|
-
declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData;
|
|
157
|
+
declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData | UnhandledBlockViewData;
|
|
134
158
|
|
|
135
159
|
/**
|
|
136
160
|
* Base view node for everything the editor renders, generic over the
|
|
@@ -151,6 +175,17 @@ export declare class BlockViewNode<T extends AnyViewData = AnyViewData> extends
|
|
|
151
175
|
constructor(data: T, dom: globalThis.Node, children: readonly ViewNode[]);
|
|
152
176
|
get block(): BlockAstNode;
|
|
153
177
|
get element(): HTMLElement;
|
|
178
|
+
/**
|
|
179
|
+
* The horizontal scroll viewport for selection/caret clipping
|
|
180
|
+
* ({@link blockViewportClip}). For most blocks the scroller *is*
|
|
181
|
+
* {@link element} — a code / math / unhandled block's `element` is the very
|
|
182
|
+
* `overflow-x: auto` box that scrolls. A table is the exception: its
|
|
183
|
+
* `element` stays the inner `<table>` (so the active/markers classes and
|
|
184
|
+
* `.md-table` theme styling are unaffected), but the box that actually
|
|
185
|
+
* scrolls is the wrapping `.md-table-wrapper`, so {@link TableViewNode}
|
|
186
|
+
* overrides this to return that wrapper.
|
|
187
|
+
*/
|
|
188
|
+
get scrollElement(): HTMLElement;
|
|
154
189
|
/**
|
|
155
190
|
* Whether this already-built node can stand in for `data` unchanged. The
|
|
156
191
|
* builder preserves view-data identity for any subtree whose ast and
|
|
@@ -174,9 +209,10 @@ export declare interface BlockViewOptions {
|
|
|
174
209
|
/**
|
|
175
210
|
* Opens a link's URL. Called when the user activates a link: a plain click
|
|
176
211
|
* while the link's block is inactive (rendered), or a Ctrl/Cmd+click while it
|
|
177
|
-
* is active (source shown).
|
|
212
|
+
* is active (source shown). Return `false` to use the anchor's native
|
|
213
|
+
* navigation behavior.
|
|
178
214
|
*/
|
|
179
|
-
readonly onOpenLink?: (url: string, event: MouseEvent) => void;
|
|
215
|
+
readonly onOpenLink?: (url: string, event: MouseEvent) => false | void;
|
|
180
216
|
/**
|
|
181
217
|
* Colours fenced code blocks. When set, a code block's content is rendered
|
|
182
218
|
* as a sequence of token spans instead of one plain text node. This is the
|
|
@@ -196,6 +232,22 @@ export declare interface BlockViewOptions {
|
|
|
196
232
|
* `katexEditableIdentifiers.ts`).
|
|
197
233
|
*/
|
|
198
234
|
readonly renderMath?: (request: MathRenderRequest) => MathRendering | undefined;
|
|
235
|
+
/**
|
|
236
|
+
* Pluggable factory for an in-place, interactive editor that replaces the
|
|
237
|
+
* *rendered* (inactive) form of a fenced code block — see
|
|
238
|
+
* {@link IEmbeddedCodeEditor}. When it returns an editor for the block's
|
|
239
|
+
* language, that editor's element is mounted instead of the highlighted
|
|
240
|
+
* code, and content flows both ways as string edits. Returning `undefined`
|
|
241
|
+
* falls back to the default rendering. EXPERIMENTAL.
|
|
242
|
+
*/
|
|
243
|
+
readonly embeddedCodeEditorFactory?: IEmbeddedCodeEditorFactory;
|
|
244
|
+
/**
|
|
245
|
+
* Called when an {@link IEmbeddedCodeEditor} edits its content. `contentEdit`
|
|
246
|
+
* is in the block's *content* coordinates; the host translates it to a
|
|
247
|
+
* document edit (via {@link CodeBlockAstNode.codeOffset} and the block's
|
|
248
|
+
* offset) and applies it to the model.
|
|
249
|
+
*/
|
|
250
|
+
readonly onEmbeddedCodeEditorEdit?: (block: CodeBlockAstNode, contentEdit: StringEdit) => void;
|
|
199
251
|
}
|
|
200
252
|
|
|
201
253
|
export declare class CodeBlockAstNode extends BlockAstNodeBase {
|
|
@@ -271,10 +323,241 @@ export declare class CodeBlockViewNode extends BlockViewNode<CodeBlockViewData>
|
|
|
271
323
|
* its predecessor's subscription explicitly.
|
|
272
324
|
*/
|
|
273
325
|
private _snapshotSub;
|
|
326
|
+
/**
|
|
327
|
+
* An in-place interactive editor (e.g. an iframe) mounted instead of the
|
|
328
|
+
* rendered code. Like {@link _session} it is adopted from `previous` across
|
|
329
|
+
* rebuilds so the underlying editor keeps its state, and must be disposed
|
|
330
|
+
* manually (a node reused as `previous` is never {@link dispose}d).
|
|
331
|
+
*/
|
|
332
|
+
private _embeddedEditor;
|
|
274
333
|
constructor(data: CodeBlockViewData, options: BlockViewOptions | undefined, previous: ViewNode | undefined);
|
|
275
334
|
dispose(): void;
|
|
276
335
|
}
|
|
277
336
|
|
|
337
|
+
/** A persistent comment anchored to a source range. */
|
|
338
|
+
declare interface Comment_2 {
|
|
339
|
+
readonly id: string;
|
|
340
|
+
/** Source range the comment refers to (its highlighted region). */
|
|
341
|
+
readonly range: OffsetRange;
|
|
342
|
+
/** The comment text. */
|
|
343
|
+
readonly body: string;
|
|
344
|
+
/** Display name of the author, if any. */
|
|
345
|
+
readonly author?: string;
|
|
346
|
+
/** Creation time (epoch ms), used to render a relative timestamp. */
|
|
347
|
+
readonly createdAt?: number;
|
|
348
|
+
}
|
|
349
|
+
export { Comment_2 as Comment }
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* A self-contained comment input box — a rounded panel with an auto-growing
|
|
353
|
+
* textarea and a send button, styled after the gdocs/Word "add a comment"
|
|
354
|
+
* affordance.
|
|
355
|
+
*
|
|
356
|
+
* This widget is *positioning-agnostic*: it only owns its own DOM and state.
|
|
357
|
+
* A host (the comment-mode controller, or a fixture) mounts {@link element}
|
|
358
|
+
* wherever it likes and is responsible for placing it relative to a selection.
|
|
359
|
+
*
|
|
360
|
+
* State is observable-driven (no framework): {@link value} reflects the live
|
|
361
|
+
* textarea content; submit/cancel are reported through the option callbacks.
|
|
362
|
+
*/
|
|
363
|
+
export declare class CommentInputWidget extends Disposable {
|
|
364
|
+
private readonly _options?;
|
|
365
|
+
readonly element: HTMLElement;
|
|
366
|
+
private readonly _textarea;
|
|
367
|
+
private readonly _measure;
|
|
368
|
+
private readonly _submitButton;
|
|
369
|
+
private readonly _value;
|
|
370
|
+
/** Live, untrimmed textarea content. */
|
|
371
|
+
get value(): IObservable<string>;
|
|
372
|
+
/** The raw textarea, exposed so a host can move focus into it (e.g. on Tab). */
|
|
373
|
+
get inputElement(): HTMLTextAreaElement;
|
|
374
|
+
constructor(_options?: CommentInputWidgetOptions | undefined);
|
|
375
|
+
/** Move focus into the textarea (caret at the end). */
|
|
376
|
+
focus(): void;
|
|
377
|
+
/** Replace the textarea content. */
|
|
378
|
+
setText(text: string): void;
|
|
379
|
+
/** Clear the textarea. */
|
|
380
|
+
clear(): void;
|
|
381
|
+
private _submit;
|
|
382
|
+
private _autoSize;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export declare interface CommentInputWidgetOptions {
|
|
386
|
+
/** Placeholder shown while the textarea is empty. Defaults to "Add Comment". */
|
|
387
|
+
readonly placeholder?: string;
|
|
388
|
+
/** Called after the textarea changes size. */
|
|
389
|
+
readonly onDidChangeSize?: () => void;
|
|
390
|
+
/**
|
|
391
|
+
* Called when the user submits a non-empty comment (Enter or the send
|
|
392
|
+
* button). The text is trimmed; never called with an empty string.
|
|
393
|
+
*/
|
|
394
|
+
readonly onSubmit?: (text: string) => void;
|
|
395
|
+
/** Called when the user dismisses the input (Escape). */
|
|
396
|
+
readonly onCancel?: () => void;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Comment mode — a gdocs/Word-style "add a comment" affordance layered on top of
|
|
401
|
+
* the editor *without modifying it*. It reads the editor's public observables
|
|
402
|
+
* ({@link EditorModel.readonlyMode}, {@link EditorModel.selection}) and the
|
|
403
|
+
* exposed {@link EditorView.caretRect} geometry, and mounts a
|
|
404
|
+
* {@link CommentInputWidget} into {@link EditorView.overlayContainer}.
|
|
405
|
+
*
|
|
406
|
+
* Behaviour:
|
|
407
|
+
* - Only active in read-only mode (the "review" view).
|
|
408
|
+
* - When the selection is non-empty, the input box appears next to the caret
|
|
409
|
+
* (the selection's active end) but does NOT take focus, so keyboard selection
|
|
410
|
+
* keeps working. Press Tab to move focus into the box, then type.
|
|
411
|
+
* - The box appears on mouse-up, not mid-drag, so it doesn't flicker/jump
|
|
412
|
+
* while a selection is being dragged out (keyboard selection shows at once).
|
|
413
|
+
* - While the box has focus or holds a draft it is frozen in place (selection
|
|
414
|
+
* changes, drags and clicks no longer move it). It is dismissed by Escape,
|
|
415
|
+
* by submitting, or by blurring an empty box.
|
|
416
|
+
* - The editor's logical caret geometry remains available for anchoring in
|
|
417
|
+
* read-only mode even though the painted caret is hidden. While the box has
|
|
418
|
+
* focus, `.md-comment-active` also suppresses the painted caret in any mode.
|
|
419
|
+
*/
|
|
420
|
+
export declare class CommentModeController extends Disposable {
|
|
421
|
+
private readonly _model;
|
|
422
|
+
private readonly _view;
|
|
423
|
+
private readonly _options?;
|
|
424
|
+
private readonly _widget;
|
|
425
|
+
private readonly _gap;
|
|
426
|
+
private _visible;
|
|
427
|
+
private _anchorX;
|
|
428
|
+
private _pinnedRange;
|
|
429
|
+
/**
|
|
430
|
+
* The range a comment was just submitted for. The box stays hidden for it
|
|
431
|
+
* until the selection changes, so submitting doesn't immediately re-summon an
|
|
432
|
+
* empty box on the still-selected text.
|
|
433
|
+
*/
|
|
434
|
+
private _submittedRange;
|
|
435
|
+
constructor(_model: EditorModel, _view: EditorView, _options?: CommentModeControllerOptions | undefined);
|
|
436
|
+
private _update;
|
|
437
|
+
private _show;
|
|
438
|
+
private _layoutHorizontally;
|
|
439
|
+
/** Force-hide and clear the box (used by Escape and submit). */
|
|
440
|
+
private _hide;
|
|
441
|
+
/**
|
|
442
|
+
* Hide unless the user is engaged with the box: it has focus or holds a
|
|
443
|
+
* non-empty draft. This preserves in-progress text and keeps a focused box
|
|
444
|
+
* open (it is dismissed explicitly via Escape/submit, or by blurring it).
|
|
445
|
+
*/
|
|
446
|
+
private _autoHide;
|
|
447
|
+
private _widgetHasFocus;
|
|
448
|
+
/**
|
|
449
|
+
* The visible viewport (client coords) used for the flip-above decision: the
|
|
450
|
+
* nearest scrollable ancestor of the editor. `.md-editor` itself spans the
|
|
451
|
+
* full document height and never clips, so measuring against it would always
|
|
452
|
+
* report room below. Falls back to the window when nothing scrolls.
|
|
453
|
+
*/
|
|
454
|
+
private _getViewportRect;
|
|
455
|
+
private _hideAndRefocus;
|
|
456
|
+
private _submit;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export declare interface CommentModeControllerOptions {
|
|
460
|
+
/** Called when the user submits a comment for the current selection. */
|
|
461
|
+
readonly onSubmit?: (submission: CommentSubmission) => void;
|
|
462
|
+
/** Gap (px) between the bottom of the selection and the top of the input box. */
|
|
463
|
+
readonly gap?: number;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/** Human-readable labels (for pickers / dropdowns). */
|
|
467
|
+
export declare const COMMENTS_DESIGN_LABELS: Record<CommentsDesign, string>;
|
|
468
|
+
|
|
469
|
+
/** design id → presenter factory over a shared CommentsModel + EditorView. */
|
|
470
|
+
export declare const COMMENTS_DESIGNS: Record<CommentsDesign, CommentsPresenterFactory>;
|
|
471
|
+
|
|
472
|
+
/** The available comment rendering designs. */
|
|
473
|
+
export declare type CommentsDesign = 'connected' | 'vscode' | 'vscode-v2';
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Seedable store of {@link Comment}s for the comment-mode contribution. Owns the
|
|
477
|
+
* comment list and the shared hover state; it has no opinion on rendering or
|
|
478
|
+
* persistence — a host seeds it via {@link set}/{@link add} and observes
|
|
479
|
+
* {@link comments}.
|
|
480
|
+
*/
|
|
481
|
+
export declare class CommentsModel {
|
|
482
|
+
private readonly _comments;
|
|
483
|
+
/** Monotonic counter for ids of comments created via {@link create}. */
|
|
484
|
+
private _sequence;
|
|
485
|
+
/** The current comments, in insertion order. */
|
|
486
|
+
get comments(): IObservable<readonly Comment_2[]>;
|
|
487
|
+
/**
|
|
488
|
+
* The comment currently hovered (by its card or its highlight), or
|
|
489
|
+
* `undefined`. Shared so the card and the highlight can react together.
|
|
490
|
+
*/
|
|
491
|
+
readonly hoveredId: ISettableObservable<string | undefined>;
|
|
492
|
+
/** Replace the whole comment set. */
|
|
493
|
+
set(comments: readonly Comment_2[]): void;
|
|
494
|
+
/**
|
|
495
|
+
* Create a comment from a user submission and append it, generating its `id`
|
|
496
|
+
* and `createdAt` here so id/time allocation stays the store's concern (the
|
|
497
|
+
* UI only supplies the range and text). Returns the created comment.
|
|
498
|
+
*/
|
|
499
|
+
create(input: {
|
|
500
|
+
range: OffsetRange;
|
|
501
|
+
body: string;
|
|
502
|
+
author?: string;
|
|
503
|
+
}): Comment_2;
|
|
504
|
+
/** Append a comment. */
|
|
505
|
+
add(comment: Comment_2): void;
|
|
506
|
+
/** Remove a comment by id. */
|
|
507
|
+
remove(id: string): void;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/** Optional, design-specific context a presenter may use (ignored by others). */
|
|
511
|
+
export declare interface CommentsPresenterContext {
|
|
512
|
+
/** Light/dark hint for the token-wrapped VS Code widget designs. */
|
|
513
|
+
readonly theme?: 'light' | 'dark';
|
|
514
|
+
/**
|
|
515
|
+
* Resolves a source offset to a 1-based line number, for designs that show
|
|
516
|
+
* line info (the VS Code V1 card). Optional because the model itself carries
|
|
517
|
+
* no text; the host (which owns the source) supplies it.
|
|
518
|
+
*/
|
|
519
|
+
readonly resolveLine?: (offset: number) => number;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/** Builds a presenter for a given model + editor view. */
|
|
523
|
+
export declare type CommentsPresenterFactory = (model: CommentsModel, view: EditorView, context?: CommentsPresenterContext) => ICommentsPresenter;
|
|
524
|
+
|
|
525
|
+
/** A comment the user submitted, with the source range it was anchored to. */
|
|
526
|
+
export declare interface CommentSubmission {
|
|
527
|
+
readonly text: string;
|
|
528
|
+
readonly range: OffsetRange;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Renders persistent comments as a gdocs-style side rail: each comment's range
|
|
533
|
+
* is highlighted (reusing the editor's selection geometry via
|
|
534
|
+
* {@link EditorView.rangeRects}), a leader line curves from the bottom of that
|
|
535
|
+
* highlight to a card stacked in the right rail, and cards never overlap.
|
|
536
|
+
*
|
|
537
|
+
* Everything is mounted into {@link EditorView.overlayContainer} so it shares
|
|
538
|
+
* the selection/caret coordinate space and scrolls with the document. When the
|
|
539
|
+
* editor's natural right margin is too narrow for the rail, the view reserves
|
|
540
|
+
* proportional space by padding the editor on the right — but only while there
|
|
541
|
+
* are comments.
|
|
542
|
+
*/
|
|
543
|
+
export declare class CommentsView extends Disposable {
|
|
544
|
+
private readonly _model;
|
|
545
|
+
private readonly _view;
|
|
546
|
+
private readonly _layer;
|
|
547
|
+
private readonly _entries;
|
|
548
|
+
constructor(_model: CommentsModel, _view: EditorView);
|
|
549
|
+
private _createLayer;
|
|
550
|
+
private _update;
|
|
551
|
+
/** Create/update/remove per-comment DOM to match `comments`. */
|
|
552
|
+
private _reconcile;
|
|
553
|
+
private _createEntry;
|
|
554
|
+
private _fillCard;
|
|
555
|
+
private _disposeEntry;
|
|
556
|
+
/** Position highlights, cards (stacked) and leader lines. */
|
|
557
|
+
private _layout;
|
|
558
|
+
private _applyHover;
|
|
559
|
+
}
|
|
560
|
+
|
|
278
561
|
/**
|
|
279
562
|
* A {@link MonacoSyntaxHighlighter} preloaded with a handful of common Monarch
|
|
280
563
|
* grammars (plus the usual short aliases). Unknown languages fall back to an
|
|
@@ -292,6 +575,8 @@ export declare interface CursorCommandContext {
|
|
|
292
575
|
readonly selection: Selection_2;
|
|
293
576
|
readonly document: DocumentAstNode;
|
|
294
577
|
readonly activeBlock: BlockAstNode | undefined;
|
|
578
|
+
readonly markerVisibleBlocks: ReadonlySet<BlockAstNode>;
|
|
579
|
+
readonly wordNavigationConfig: WordNavigationConfig;
|
|
295
580
|
}
|
|
296
581
|
|
|
297
582
|
export declare const cursorDocumentEnd: CursorCommand;
|
|
@@ -300,6 +585,8 @@ export declare const cursorDocumentStart: CursorCommand;
|
|
|
300
585
|
|
|
301
586
|
export declare const cursorDown: VisualCursorCommand;
|
|
302
587
|
|
|
588
|
+
export declare type CursorKeyboardAction = 'left' | 'right' | 'up' | 'down' | 'wordLeft' | 'wordRight' | 'visualLineStart' | 'visualLineEnd' | 'logicalLineStart' | 'logicalLineEnd' | 'documentStart' | 'documentEnd';
|
|
589
|
+
|
|
303
590
|
export declare const cursorLeft: CursorCommand;
|
|
304
591
|
|
|
305
592
|
export declare const cursorLineEnd: CursorCommand;
|
|
@@ -329,15 +616,27 @@ export declare const cursorUp: VisualCursorCommand;
|
|
|
329
616
|
* derived subscribed.
|
|
330
617
|
*/
|
|
331
618
|
export declare class CursorView extends Disposable {
|
|
332
|
-
private readonly _parent;
|
|
333
619
|
readonly element: HTMLElement;
|
|
334
620
|
readonly rendering: IObservable<CursorViewRendering>;
|
|
335
|
-
constructor(
|
|
621
|
+
constructor(options: CursorViewOptions);
|
|
336
622
|
}
|
|
337
623
|
|
|
338
624
|
export declare interface CursorViewOptions {
|
|
339
625
|
readonly offset: IObservable<SourceOffset | undefined>;
|
|
340
626
|
readonly visualLineMap: IObservable<VisualLineMap>;
|
|
627
|
+
/**
|
|
628
|
+
* The mounted blocks, used to hide the caret when it sits at an offset that
|
|
629
|
+
* has been scrolled out of its (horizontally scrolling) block's viewport —
|
|
630
|
+
* matching how the selection is clipped there.
|
|
631
|
+
*/
|
|
632
|
+
readonly blocks?: IObservable<readonly SelectionBlock[]>;
|
|
633
|
+
/**
|
|
634
|
+
* When set, the caret is drawn over the transient empty paragraph instead
|
|
635
|
+
* of at {@link offset} — its editor-local rect comes straight
|
|
636
|
+
* from that synthetic element's geometry, since it has no visual-line-map
|
|
637
|
+
* entry. Takes priority over the normal offset-based placement.
|
|
638
|
+
*/
|
|
639
|
+
readonly pendingCaretRect?: IObservable<Rect2D | undefined>;
|
|
341
640
|
}
|
|
342
641
|
|
|
343
642
|
export declare class CursorViewRendering {
|
|
@@ -347,18 +646,98 @@ export declare class CursorViewRendering {
|
|
|
347
646
|
constructor(offset: SourceOffset, visible: boolean, rect: Rect2D);
|
|
348
647
|
}
|
|
349
648
|
|
|
649
|
+
export declare const cursorVisualLineEnd: VisualCursorCommand;
|
|
650
|
+
|
|
651
|
+
export declare const cursorVisualLineStart: VisualCursorCommand;
|
|
652
|
+
|
|
350
653
|
export declare const cursorWordLeft: CursorCommand;
|
|
351
654
|
|
|
352
655
|
export declare const cursorWordRight: CursorCommand;
|
|
353
656
|
|
|
657
|
+
export declare const DEFAULT_WORD_NAVIGATION_CONFIG: WordNavigationConfig;
|
|
658
|
+
|
|
659
|
+
export declare const DEFAULT_WORD_SEPARATORS = "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?";
|
|
660
|
+
|
|
354
661
|
export declare const deleteLeft: EditCommand;
|
|
355
662
|
|
|
663
|
+
export declare const deleteLineLeft: EditCommand;
|
|
664
|
+
|
|
665
|
+
export declare const deleteLineRight: EditCommand;
|
|
666
|
+
|
|
356
667
|
export declare const deleteRight: EditCommand;
|
|
357
668
|
|
|
358
669
|
export declare const deleteWordLeft: EditCommand;
|
|
359
670
|
|
|
360
671
|
export declare const deleteWordRight: EditCommand;
|
|
361
672
|
|
|
673
|
+
/**
|
|
674
|
+
* A read-only "removed" decoration: an original block rendered (red) above its
|
|
675
|
+
* place in the modified document, occupying vertical space like a view-zone but
|
|
676
|
+
* contributing **zero** source length, so the editor's source mapping stays the
|
|
677
|
+
* modified document and editing is unaffected. Used for `removed` and the
|
|
678
|
+
* original side of a `replaced` block in editor diff mode.
|
|
679
|
+
*/
|
|
680
|
+
declare class DiffDecorationViewData {
|
|
681
|
+
readonly ast: AstNode;
|
|
682
|
+
readonly side: BlockViewData;
|
|
683
|
+
readonly deletedRanges: readonly DiffHighlightRange[];
|
|
684
|
+
/** True when the whole block was removed: solid red band, no word rects. */
|
|
685
|
+
readonly whole: boolean;
|
|
686
|
+
/** Absolute offset of this block in the *original* document. */
|
|
687
|
+
readonly originalStart: number;
|
|
688
|
+
readonly kind = "diffDecoration";
|
|
689
|
+
constructor(ast: AstNode, side: BlockViewData, deletedRanges: readonly DiffHighlightRange[],
|
|
690
|
+
/** True when the whole block was removed: solid red band, no word rects. */
|
|
691
|
+
whole: boolean,
|
|
692
|
+
/** Absolute offset of this block in the *original* document. */
|
|
693
|
+
originalStart: number);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/** A word/character highlight inside one diff side, in block-local coords. */
|
|
697
|
+
declare interface DiffHighlightRange {
|
|
698
|
+
readonly range: OffsetRange;
|
|
699
|
+
readonly kind: 'inserted' | 'deleted';
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* A changed block rendered as its original form stacked over its modified form
|
|
704
|
+
* (either side may be absent for a pure deletion/insertion). It is itself a
|
|
705
|
+
* document child the renderer mounts like a block; its {@link ast} is the
|
|
706
|
+
* surviving side's ast, used only for view-node identity/reuse.
|
|
707
|
+
*/
|
|
708
|
+
declare class DiffHunkViewData {
|
|
709
|
+
readonly ast: AstNode;
|
|
710
|
+
readonly original: DiffSideViewData | undefined;
|
|
711
|
+
readonly modified: DiffSideViewData | undefined;
|
|
712
|
+
readonly kind = "diffHunk";
|
|
713
|
+
constructor(ast: AstNode, original: DiffSideViewData | undefined, modified: DiffSideViewData | undefined);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* The recursive classification of a diff. Each item describes one aligned
|
|
718
|
+
* position in the merged document:
|
|
719
|
+
*
|
|
720
|
+
* - `unchanged` — render the (modified) node once, neutral.
|
|
721
|
+
* - `added` — exists only in the modified document (green).
|
|
722
|
+
* - `removed` — exists only in the original document (red).
|
|
723
|
+
* - `replaced` — a *leaf* block changed in place → render original over
|
|
724
|
+
* modified, with word-level {@link AnnotatedRange}s on each.
|
|
725
|
+
* - `nested` — a *container* changed → render it once and diff its
|
|
726
|
+
* {@link NestedItem.children} recursively.
|
|
727
|
+
*
|
|
728
|
+
* Offsets ({@link UnchangedItem.modifiedStart} etc.) are absolute in their
|
|
729
|
+
* respective documents, so a renderer/visualizer can slice the source text.
|
|
730
|
+
*/
|
|
731
|
+
declare type DiffItem = UnchangedItem | AddedItem | RemovedItem | ReplacedItem | NestedItem;
|
|
732
|
+
|
|
733
|
+
/** One side (original or modified) of a {@link DiffHunkViewData}. */
|
|
734
|
+
declare interface DiffSideViewData {
|
|
735
|
+
readonly view: BlockViewData;
|
|
736
|
+
/** Render in active form (markers/whitespace visible). */
|
|
737
|
+
readonly active: boolean;
|
|
738
|
+
readonly ranges: readonly DiffHighlightRange[];
|
|
739
|
+
}
|
|
740
|
+
|
|
362
741
|
export declare class DocumentAstNode extends AstNode {
|
|
363
742
|
readonly content: readonly (BlockAstNode | GlueAstNode)[];
|
|
364
743
|
readonly kind = "document";
|
|
@@ -383,13 +762,21 @@ declare interface DocumentBlockViewData {
|
|
|
383
762
|
readonly view: BlockViewData;
|
|
384
763
|
}
|
|
385
764
|
|
|
386
|
-
/** A mounted document child: a block
|
|
765
|
+
/** A mounted document child: a block, a run of inter-block glue, the
|
|
766
|
+
* transient empty paragraph (see {@link PendingParagraphViewData}), or a
|
|
767
|
+
* {@link DiffHunkViewData diff hunk} (stacked original/modified blocks). */
|
|
387
768
|
declare interface DocumentChildViewData {
|
|
388
769
|
readonly absoluteStart: number;
|
|
389
770
|
/** For a block: selection reaches it. For glue: always false (unowned, hidden). */
|
|
390
771
|
readonly isActive: boolean;
|
|
391
|
-
readonly view: BlockViewData | GlueViewData;
|
|
392
|
-
readonly kind: 'block' | 'glue';
|
|
772
|
+
readonly view: BlockViewData | GlueViewData | PendingParagraphViewData | DiffHunkViewData | DiffDecorationViewData;
|
|
773
|
+
readonly kind: 'block' | 'glue' | 'pendingParagraph' | 'diffHunk' | 'diffDecoration';
|
|
774
|
+
/**
|
|
775
|
+
* Diff mode: how this (modified) block changed. `added` = a whole new block
|
|
776
|
+
* (strong green band, no inline rects); `modified` = a partial change (light
|
|
777
|
+
* band + inline rects on the changed words).
|
|
778
|
+
*/
|
|
779
|
+
readonly diffKind?: 'added' | 'modified';
|
|
393
780
|
}
|
|
394
781
|
|
|
395
782
|
/**
|
|
@@ -445,6 +832,8 @@ declare class DocumentViewData {
|
|
|
445
832
|
*/
|
|
446
833
|
export declare class DocumentViewNode extends ViewNode {
|
|
447
834
|
readonly blocks: readonly DocumentBlock[];
|
|
835
|
+
/** The transient empty-paragraph element, when one is armed. */
|
|
836
|
+
readonly pendingElement?: HTMLElement | undefined;
|
|
448
837
|
static create(viewData: DocumentViewData, options: BlockViewOptions | undefined, previous: DocumentViewNode | undefined): DocumentViewNode;
|
|
449
838
|
private constructor();
|
|
450
839
|
/** The stable content element this document mounts its children into. */
|
|
@@ -466,6 +855,8 @@ export declare type EditCommand = (ctx: CursorCommandContext) => {
|
|
|
466
855
|
readonly selection: Selection_2;
|
|
467
856
|
} | undefined;
|
|
468
857
|
|
|
858
|
+
export declare type EditKeyboardAction = 'deleteLeft' | 'deleteRight' | 'deleteWordLeft' | 'deleteWordRight' | 'deleteLineLeft' | 'deleteLineRight';
|
|
859
|
+
|
|
469
860
|
/**
|
|
470
861
|
* Translates raw browser input (mouse, keyboard, EditContext) into model
|
|
471
862
|
* mutations. Knows about DOM event types but never reads/writes the DOM
|
|
@@ -474,25 +865,63 @@ export declare type EditCommand = (ctx: CursorCommandContext) => {
|
|
|
474
865
|
*
|
|
475
866
|
* Owns the only non-derivable controller state:
|
|
476
867
|
* - `_desiredColumn` — sticky column for up/down navigation
|
|
868
|
+
* - `_clickCount` / `_lastPointerDown` — multi-click detection for pointer
|
|
869
|
+
* input, since `pointerdown` events (unlike `mousedown`) don't populate
|
|
870
|
+
* `detail` with a click count.
|
|
477
871
|
*/
|
|
478
872
|
export declare class EditorController extends Disposable {
|
|
479
873
|
private readonly _model;
|
|
480
874
|
private readonly _view;
|
|
481
875
|
private _desiredColumn;
|
|
876
|
+
private readonly _keyboardPlatform;
|
|
877
|
+
private readonly _keyboardProfile;
|
|
878
|
+
private readonly _historyStrategy;
|
|
879
|
+
/** Running click count for the current multi-click sequence (1, 2, 3, …). */
|
|
880
|
+
private _clickCount;
|
|
881
|
+
/** Timestamp and position of the previous pointer-down, for multi-click detection. */
|
|
882
|
+
private _lastPointerDown;
|
|
482
883
|
constructor(_model: EditorModel, _view: EditorView, options?: EditorControllerOptions);
|
|
483
884
|
private readonly _handleTextUpdate;
|
|
484
|
-
private readonly
|
|
885
|
+
private readonly _handlePointerDown;
|
|
485
886
|
private _makeCursorContext;
|
|
486
887
|
private _makeVisualCursorContext;
|
|
487
888
|
private _executeCursorCommand;
|
|
488
889
|
private _executeEditCommand;
|
|
890
|
+
private _runUndoableEdit;
|
|
489
891
|
private _executeVisualCursorCommand;
|
|
490
892
|
/** Move the cursor down one visual line (Arrow Down). */
|
|
491
893
|
cursorDown(extend?: boolean): void;
|
|
492
894
|
/** Move the cursor up one visual line (Arrow Up). */
|
|
493
895
|
cursorUp(extend?: boolean): void;
|
|
494
896
|
private _selectedText;
|
|
897
|
+
private readonly _updateModifierState;
|
|
898
|
+
private readonly _clearModifierState;
|
|
899
|
+
/**
|
|
900
|
+
* Drop any native DOM selection over the rendered text.
|
|
901
|
+
*
|
|
902
|
+
* The editor paints selection from `model.selection`, so a browser
|
|
903
|
+
* selection there is always spurious: nothing reads it (copy/cut read the
|
|
904
|
+
* model, hit-testing uses the measured layout) and nothing clears it, so it
|
|
905
|
+
* lingers as a second highlight even after the caret moves away.
|
|
906
|
+
* {@link isCaretMotionKey} stops the common source synchronously; this is
|
|
907
|
+
* the backstop for the rest of the browser's editing commands, which are
|
|
908
|
+
* platform- and version-specific and cannot be enumerated (Shift+PageDown
|
|
909
|
+
* and macOS Shift+Ctrl+B both reach one today).
|
|
910
|
+
*
|
|
911
|
+
* Scoped twice so it only ever discards selections the editor owns: the
|
|
912
|
+
* range must touch the rendered text (overlays such as comment widgets sit
|
|
913
|
+
* beside it and stay selectable), and input focus must still be inside this
|
|
914
|
+
* editor (so a host find-in-page, which selects while its own input is
|
|
915
|
+
* focused, is left alone).
|
|
916
|
+
*/
|
|
917
|
+
private readonly _discardNativeSelection;
|
|
495
918
|
private readonly _handleKeyDown;
|
|
919
|
+
private _executeKeyboardAction;
|
|
920
|
+
/**
|
|
921
|
+
* Context-aware Enter: splits / line-breaks via {@link insertSmartEnter}, or
|
|
922
|
+
* arms a transient empty paragraph when at the end of a paragraph.
|
|
923
|
+
*/
|
|
924
|
+
private _smartEnter;
|
|
496
925
|
}
|
|
497
926
|
|
|
498
927
|
/** Options for an {@link EditorController}. */
|
|
@@ -503,8 +932,61 @@ export declare interface EditorControllerOptions {
|
|
|
503
932
|
* strategy (e.g. `AsyncClipboardStrategy`) in hosts that swallow them.
|
|
504
933
|
*/
|
|
505
934
|
readonly clipboardStrategy?: IClipboardStrategy;
|
|
935
|
+
/**
|
|
936
|
+
* Where undo and redo are executed: `LocalHistoryStrategy` for a
|
|
937
|
+
* self-contained editor, or a strategy that forwards to the host's own
|
|
938
|
+
* document history. Left unset, the chords are passed on to the host.
|
|
939
|
+
*/
|
|
940
|
+
readonly historyStrategy?: IHistoryStrategy;
|
|
941
|
+
readonly keyboardPlatform?: KeyboardPlatform;
|
|
942
|
+
readonly keyboardProfile?: KeyboardProfile;
|
|
506
943
|
}
|
|
507
944
|
|
|
945
|
+
/**
|
|
946
|
+
* The editor overlay's local CSS-pixel coordinate space.
|
|
947
|
+
*
|
|
948
|
+
* Browser geometry and pointer APIs expose viewport client coordinates. This
|
|
949
|
+
* boundary converts them immediately into the coordinate system shared by the
|
|
950
|
+
* editor content and its overlays. Range rectangles are axis-aligned, so the
|
|
951
|
+
* current implementation deliberately supports positive axis-aligned scale and
|
|
952
|
+
* translation only.
|
|
953
|
+
*/
|
|
954
|
+
export declare class EditorCoordinateSpace {
|
|
955
|
+
private readonly _getLocalToClientMatrix;
|
|
956
|
+
static forSvgOverlay(overlay: SVGSVGElement): EditorCoordinateSpace;
|
|
957
|
+
private constructor();
|
|
958
|
+
capture(): EditorCoordinateTransform;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/** A stable coordinate conversion captured for one measurement operation. */
|
|
962
|
+
export declare class EditorCoordinateTransform {
|
|
963
|
+
private readonly _localToClient;
|
|
964
|
+
private readonly _clientToLocal;
|
|
965
|
+
constructor(_localToClient: DOMMatrix);
|
|
966
|
+
toLocalPoint(point: Pick<Point2D, 'x' | 'y'>): Point2D;
|
|
967
|
+
toClientPoint(point: Pick<Point2D, 'x' | 'y'>): Point2D;
|
|
968
|
+
toLocalRect(rect: Pick<DOMRectReadOnly, 'left' | 'top' | 'width' | 'height'>): Rect2D;
|
|
969
|
+
toClientRect(rect: Pick<Rect2D, 'left' | 'top' | 'width' | 'height'>): Rect2D;
|
|
970
|
+
private _convertRect;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
export declare type EditorKeyboardAction = {
|
|
974
|
+
readonly kind: 'cursor';
|
|
975
|
+
readonly command: CursorKeyboardAction;
|
|
976
|
+
readonly extend: boolean;
|
|
977
|
+
} | {
|
|
978
|
+
readonly kind: 'edit';
|
|
979
|
+
readonly command: EditKeyboardAction;
|
|
980
|
+
} | {
|
|
981
|
+
readonly kind: 'history';
|
|
982
|
+
readonly command: HistoryKeyboardAction;
|
|
983
|
+
} | {
|
|
984
|
+
readonly kind: 'selectAll';
|
|
985
|
+
} | {
|
|
986
|
+
readonly kind: 'enter';
|
|
987
|
+
readonly command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak';
|
|
988
|
+
};
|
|
989
|
+
|
|
508
990
|
export declare class EditorModel {
|
|
509
991
|
private readonly _parser;
|
|
510
992
|
/**
|
|
@@ -515,11 +997,44 @@ export declare class EditorModel {
|
|
|
515
997
|
*/
|
|
516
998
|
private _pendingEdit;
|
|
517
999
|
readonly sourceText: ISettableObservable<StringValue, void>;
|
|
1000
|
+
readonly wordNavigationConfig: ISettableObservable<WordNavigationConfig, void>;
|
|
1001
|
+
/**
|
|
1002
|
+
* Read-only mode. When `true`, the editor never reveals a block's source
|
|
1003
|
+
* markers (markdown special characters like `**`, `#`, list bullets, code
|
|
1004
|
+
* fences, `$…$`) — every block stays in its clean rendered form regardless
|
|
1005
|
+
* of where the caret/selection is — and source-mutating edits are ignored.
|
|
1006
|
+
* Plain text selection still works everywhere (so the user can copy). The
|
|
1007
|
+
* default (`false`) is the normal editing mode where the active block
|
|
1008
|
+
* reveals its markers.
|
|
1009
|
+
*/
|
|
1010
|
+
readonly readonlyMode: ISettableObservable<boolean, void>;
|
|
518
1011
|
/**
|
|
519
1012
|
* The current selection, or `undefined` when the editor has no caret
|
|
520
1013
|
* (e.g. an inactive/unfocused rendering).
|
|
521
1014
|
*/
|
|
522
1015
|
readonly selection: ISettableObservable<Selection_2 | undefined, void>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Whether a Ctrl/Cmd modifier is currently held. Set by the controller from
|
|
1018
|
+
* live keyboard state; the view reads it to show the link-open affordance
|
|
1019
|
+
* (underline + pointer cursor) only while a Ctrl/Cmd+click would open a link
|
|
1020
|
+
* whose block is active.
|
|
1021
|
+
*/
|
|
1022
|
+
readonly ctrlOrMetaDown: ISettableObservable<boolean, void>;
|
|
1023
|
+
/**
|
|
1024
|
+
* Whether a pointer-driven selection drag is currently in progress. Set by
|
|
1025
|
+
* the controller between the pointer-down that starts the drag and the
|
|
1026
|
+
* pointer-up/cancel that ends it. Contributions read it to defer UI that
|
|
1027
|
+
* would otherwise flicker mid-drag (e.g. the comment input box appears only
|
|
1028
|
+
* once the drag ends).
|
|
1029
|
+
*/
|
|
1030
|
+
readonly isSelecting: ISettableObservable<boolean, void>;
|
|
1031
|
+
/**
|
|
1032
|
+
* Gutter markers (source-control style change indicators) painted in the
|
|
1033
|
+
* left gutter. Each entry maps a source {@link OffsetRange} to a change kind
|
|
1034
|
+
* — see {@link GutterMarker}. Purely decorative: markers never affect the
|
|
1035
|
+
* parsed {@link document}, selection, or layout. Empty by default.
|
|
1036
|
+
*/
|
|
1037
|
+
readonly gutterMarkers: ISettableObservable<readonly GutterMarker[], void>;
|
|
523
1038
|
/**
|
|
524
1039
|
* Forces the rendered active-block set. `undefined` (the default)
|
|
525
1040
|
* derives the set from the current selection range (see
|
|
@@ -528,6 +1043,13 @@ export declare class EditorModel {
|
|
|
528
1043
|
* collapsed/inactive rendering.
|
|
529
1044
|
*/
|
|
530
1045
|
readonly activeBlocksOverride: ISettableObservable<readonly BlockAstNode[] | typeof NO_ACTIVE_BLOCKS | undefined, void>;
|
|
1046
|
+
/**
|
|
1047
|
+
* The transient empty-paragraph editing state, or `undefined` when none is
|
|
1048
|
+
* armed. See {@link PendingParagraph}. This is *not* document data — it is
|
|
1049
|
+
* cleared by any source edit and lives only between the Enter that armed it
|
|
1050
|
+
* and the next keystroke.
|
|
1051
|
+
*/
|
|
1052
|
+
readonly pendingParagraph: ISettableObservable<PendingParagraph | undefined, void>;
|
|
531
1053
|
readonly cursorOffset: IObservableWithChange<number | undefined, void>;
|
|
532
1054
|
/**
|
|
533
1055
|
* The parsed document. Threads the previous document into the parser so
|
|
@@ -551,7 +1073,51 @@ export declare class EditorModel {
|
|
|
551
1073
|
* collapsed this is a one-element set holding {@link activeBlock}.
|
|
552
1074
|
*/
|
|
553
1075
|
readonly activeBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
|
|
554
|
-
|
|
1076
|
+
/**
|
|
1077
|
+
* The baseline document to diff against. When set, the editor renders in
|
|
1078
|
+
* diff mode: the modified document ({@link document}) stays editable, while
|
|
1079
|
+
* the baseline's removed/changed blocks are shown as read-only decorations.
|
|
1080
|
+
* `undefined` (the default) renders normally.
|
|
1081
|
+
*/
|
|
1082
|
+
readonly baseline: ISettableObservable<StringValue | undefined, void>;
|
|
1083
|
+
private readonly _baselineDocument;
|
|
1084
|
+
/**
|
|
1085
|
+
* The diff of {@link baseline} → {@link document}, or `undefined` when no
|
|
1086
|
+
* baseline is set. The view renders the {@link DiffItem}s as stacked
|
|
1087
|
+
* decorations; `insertedRanges` (modified-side change spans) drive the green
|
|
1088
|
+
* word-level highlight.
|
|
1089
|
+
*/
|
|
1090
|
+
readonly diff: IObservableWithChange< {
|
|
1091
|
+
items: DiffItem[];
|
|
1092
|
+
insertedRanges: OffsetRange[];
|
|
1093
|
+
changedBlocks: Set<BlockAstNode>;
|
|
1094
|
+
} | undefined, void>;
|
|
1095
|
+
readonly markerVisibleBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
|
|
1096
|
+
/**
|
|
1097
|
+
* Arm a {@link PendingParagraph} at the given gap, minting a fresh synthetic
|
|
1098
|
+
* AST node for it, and park the caret at the gap start. No source edit is
|
|
1099
|
+
* applied — the blank line exists only in the view until it is materialized.
|
|
1100
|
+
*/
|
|
1101
|
+
armPendingParagraph(req: {
|
|
1102
|
+
anchorBlock: BlockAstNode;
|
|
1103
|
+
replaceRange: OffsetRange;
|
|
1104
|
+
atEof: boolean;
|
|
1105
|
+
}): void;
|
|
1106
|
+
/** Discard the pending paragraph (if any) without touching the source. */
|
|
1107
|
+
cancelPendingParagraph(): void;
|
|
1108
|
+
/**
|
|
1109
|
+
* Replace the source with an authoritative value from the host, mapping the
|
|
1110
|
+
* selection through the changed span and atomically discarding transient
|
|
1111
|
+
* state anchored to the previous parse.
|
|
1112
|
+
*/
|
|
1113
|
+
replaceSourceText(text: StringValue): void;
|
|
1114
|
+
/**
|
|
1115
|
+
* Turn the pending paragraph into real source: rewrite its gap so the typed
|
|
1116
|
+
* `text` becomes its own paragraph, separated from its neighbours by blank
|
|
1117
|
+
* lines, and place the caret after the inserted text.
|
|
1118
|
+
*/
|
|
1119
|
+
materializePendingParagraph(text: string): void;
|
|
1120
|
+
applyEdit(edit: StringEdit, selection?: Selection_2): void;
|
|
555
1121
|
applyEditForSelection(edit: StringEdit): void;
|
|
556
1122
|
}
|
|
557
1123
|
|
|
@@ -584,6 +1150,7 @@ export declare class EditorView extends Disposable {
|
|
|
584
1150
|
readonly element: HTMLElement;
|
|
585
1151
|
readonly editContext: EditContext;
|
|
586
1152
|
readonly measuredLayout: MeasuredLayoutModel;
|
|
1153
|
+
readonly coordinateSpace: EditorCoordinateSpace;
|
|
587
1154
|
/**
|
|
588
1155
|
* Inner container that holds the rendered document and the cursor/selection
|
|
589
1156
|
* overlays. The outer {@link element} spans the full width; this container
|
|
@@ -593,6 +1160,9 @@ export declare class EditorView extends Disposable {
|
|
|
593
1160
|
private readonly _contentContainer;
|
|
594
1161
|
private readonly _cursorView;
|
|
595
1162
|
private readonly _selectionView;
|
|
1163
|
+
private readonly _gutterMarkersView;
|
|
1164
|
+
private readonly _diffHighlightsView;
|
|
1165
|
+
private _readonlyToggleButton;
|
|
596
1166
|
/**
|
|
597
1167
|
* The mounted block sequence, in source order. Rebuilt (not mutated) each
|
|
598
1168
|
* frame by {@link DocumentViewNode.create}; the view just swaps one
|
|
@@ -612,20 +1182,135 @@ export declare class EditorView extends Disposable {
|
|
|
612
1182
|
/** The current view-data tree (AST overlaid with selection flags), for debugging. */
|
|
613
1183
|
private readonly _viewData;
|
|
614
1184
|
get viewData(): IObservable<DocumentViewData | undefined>;
|
|
1185
|
+
/**
|
|
1186
|
+
* Whether the editor is genuinely focused: focus rests somewhere inside the
|
|
1187
|
+
* editor subtree *and* its window is focused. Mirrored onto the root as
|
|
1188
|
+
* `.md-focused`, which gates the painted caret — the blinking cursor is only
|
|
1189
|
+
* shown while this is `true`, so it never blinks in an unfocused editor or
|
|
1190
|
+
* after the window loses focus. Only the caret's visibility is affected; the
|
|
1191
|
+
* logical selection and caret geometry ({@link caretRect}) are unchanged.
|
|
1192
|
+
*/
|
|
1193
|
+
private readonly _focused;
|
|
1194
|
+
get focused(): IObservable<boolean>;
|
|
1195
|
+
/**
|
|
1196
|
+
* Caret rect (editor-local coordinates) for the transient empty paragraph, or
|
|
1197
|
+
* `undefined` when none is armed. Set each frame from the synthetic
|
|
1198
|
+
* paragraph element's geometry and fed to the {@link CursorView}, which has
|
|
1199
|
+
* no visual-line-map entry to place the caret from otherwise.
|
|
1200
|
+
*/
|
|
1201
|
+
private readonly _pendingCaretRect;
|
|
615
1202
|
/**
|
|
616
1203
|
* The block cache projected for views (selection painting) that need to
|
|
617
1204
|
* react to mount/unmount. Derived from {@link _document}, so it stays in
|
|
618
1205
|
* lock-step without any manual bookkeeping.
|
|
619
1206
|
*/
|
|
620
1207
|
private readonly _selectionBlocksObs;
|
|
1208
|
+
/**
|
|
1209
|
+
* The caret rect (zero width) at the selection's active end, in
|
|
1210
|
+
* {@link overlayContainer}-local coordinates, or `undefined` when there is no
|
|
1211
|
+
* caret. This is the same geometry the editor paints its cursor from, so
|
|
1212
|
+
* contributions (e.g. comment mode) can anchor an overlay to the active end of
|
|
1213
|
+
* the selection — where the user's cursor is — without re-deriving geometry.
|
|
1214
|
+
*/
|
|
1215
|
+
private readonly _caretRect;
|
|
1216
|
+
get caretRect(): IObservable<Rect2D | undefined>;
|
|
1217
|
+
/**
|
|
1218
|
+
* The container that establishes the positioning context for the editor's
|
|
1219
|
+
* overlays (cursor, selection, gutter). Contributions mount their own
|
|
1220
|
+
* absolutely-positioned overlays here so they share the coordinate space of
|
|
1221
|
+
* {@link caretRect}.
|
|
1222
|
+
*/
|
|
1223
|
+
get overlayContainer(): HTMLElement;
|
|
1224
|
+
/**
|
|
1225
|
+
* Selection-style rectangles covering `range`, in {@link overlayContainer}-
|
|
1226
|
+
* local coordinates — the same geometry the live selection paints. Exposed so
|
|
1227
|
+
* contributions (e.g. persistent comments) can highlight arbitrary ranges and
|
|
1228
|
+
* anchor overlays to them. Recomputes when the measured layout changes.
|
|
1229
|
+
*/
|
|
1230
|
+
rangeRects(range: OffsetRange): IObservable<readonly SelectionRect[]>;
|
|
621
1231
|
constructor(_model: EditorModel, _options?: EditorViewOptions | undefined);
|
|
1232
|
+
/**
|
|
1233
|
+
* Mirrors the model's live Ctrl/Cmd state onto the editor root as
|
|
1234
|
+
* `.md-mod-down` so CSS can show the link-open underline and pointer cursor
|
|
1235
|
+
* only while a click would actually open the link: an inactive link opens on
|
|
1236
|
+
* a plain click, but an active link only opens with the modifier held.
|
|
1237
|
+
*/
|
|
1238
|
+
private _setupModifierTracking;
|
|
1239
|
+
/**
|
|
1240
|
+
* Tracks whether the editor is genuinely focused and mirrors it onto the
|
|
1241
|
+
* root as `.md-focused` so CSS can gate the painted caret. "Focused" means
|
|
1242
|
+
* focus rests somewhere inside the editor subtree *and* the window itself is
|
|
1243
|
+
* focused; either condition failing (focus moving elsewhere, or the window
|
|
1244
|
+
* losing focus) hides the blinking caret while leaving the logical selection
|
|
1245
|
+
* and caret geometry intact.
|
|
1246
|
+
*/
|
|
1247
|
+
private _setupFocusTracking;
|
|
1248
|
+
/**
|
|
1249
|
+
* Renders the edit/read-only mode toggle. It flips the model's
|
|
1250
|
+
* {@link EditorModel.readonlyMode}: when locked (read-only) every block stays
|
|
1251
|
+
* in its clean rendered form (no markdown markers revealed) and edits are
|
|
1252
|
+
* ignored, while text selection still works. The control lives in a
|
|
1253
|
+
* zero-height *sticky* host inside the centered content container, so the
|
|
1254
|
+
* lock follows the content's right edge and remains pinned as the document
|
|
1255
|
+
* scrolls. The current mode is also mirrored onto the root as `.md-readonly`
|
|
1256
|
+
* for any CSS hooks.
|
|
1257
|
+
*/
|
|
1258
|
+
private _setupReadonlyToggle;
|
|
1259
|
+
/** Draws attention to the mode toggle after text input is attempted while locked. */
|
|
1260
|
+
showReadonlyEditingAttempt(): void;
|
|
622
1261
|
focus(): void;
|
|
1262
|
+
/**
|
|
1263
|
+
* Samples the ambient focus state that decides whether taking focus on open
|
|
1264
|
+
* would steal it from an explicit user target: whether the window is focused
|
|
1265
|
+
* and whether focus is still unclaimed (no active element, or the `<body>`
|
|
1266
|
+
* fallback).
|
|
1267
|
+
*/
|
|
1268
|
+
private _sampleAutoFocusEnvironment;
|
|
1269
|
+
/**
|
|
1270
|
+
* One-shot guarded focus attempt: focuses the editor only if doing so will
|
|
1271
|
+
* not steal focus from an explicit user target — the window must already be
|
|
1272
|
+
* focused and no other element may have claimed focus yet. Returns whether
|
|
1273
|
+
* focus was taken. A no-op for a background window or when the user has
|
|
1274
|
+
* already focused something else. {@link autoFocusOnOpen} builds the
|
|
1275
|
+
* open-time behavior on top of this primitive.
|
|
1276
|
+
*/
|
|
1277
|
+
tryAutoFocus(): boolean;
|
|
1278
|
+
/**
|
|
1279
|
+
* Focuses the editor when it opens without ever stealing focus from an
|
|
1280
|
+
* explicit user target. Tries once immediately; if the window is not focused
|
|
1281
|
+
* yet — a common open-time race where the editor is mounted before the host
|
|
1282
|
+
* routes focus to its window — the guarded attempt is deferred to the next
|
|
1283
|
+
* time the window gains focus and re-evaluated then. The deferral is
|
|
1284
|
+
* one-shot, so a later, unrelated window refocus never grabs focus, and the
|
|
1285
|
+
* re-check still respects any target the user has claimed in the meantime.
|
|
1286
|
+
*/
|
|
1287
|
+
autoFocusOnOpen(): void;
|
|
1288
|
+
/**
|
|
1289
|
+
* Own point→offset resolution. When `true` (the default),
|
|
1290
|
+
* {@link resolveOffsetFromPoint} ignores the platform DOM hit-test
|
|
1291
|
+
* (`caretPositionFromPoint`) and snaps the point to the nearest offset purely
|
|
1292
|
+
* from the rendered {@link VisualLineMap} geometry — picking the nearest
|
|
1293
|
+
* visual line by `y`, then the nearest offset on it by `x`. Because a table
|
|
1294
|
+
* row's cells share one horizontal line band, this makes the whole width of a
|
|
1295
|
+
* row resolve into that row (rather than only the cell boxes), with no visible
|
|
1296
|
+
* layout change. It also lets a drag keep extending toward off-viewport points
|
|
1297
|
+
* (e.g. the pointer leaving the window), which the platform hit-test cannot
|
|
1298
|
+
* resolve. Set to `false` to fall back to the platform DOM hit-test.
|
|
1299
|
+
*/
|
|
1300
|
+
readonly geometricHitTest: ISettableObservable<boolean, void>;
|
|
623
1301
|
/**
|
|
624
1302
|
* Client coordinates → absolute source offset (any block). Used during
|
|
625
1303
|
* drag to keep extending the selection even when the pointer leaves the
|
|
626
|
-
* original block.
|
|
1304
|
+
* original block. Honours {@link geometricHitTest}.
|
|
627
1305
|
*/
|
|
628
1306
|
resolveOffsetFromPoint(point: Point2D): SourceOffset | undefined;
|
|
1307
|
+
/**
|
|
1308
|
+
* Resolve table-cell hits that have no measurable text run. Empty cells map
|
|
1309
|
+
* from their own box instead of snapping to a neighboring cell; element-only
|
|
1310
|
+
* content (for example an inactive image) maps through the hit element's view
|
|
1311
|
+
* node. Text-bearing cells keep the normal pixel-precise line-map/DOM path.
|
|
1312
|
+
*/
|
|
1313
|
+
private _resolveTableCellOffset;
|
|
629
1314
|
/**
|
|
630
1315
|
* Whether a client point falls on the rendered document content, as
|
|
631
1316
|
* opposed to the surrounding editor padding (the green area). Uses DOM
|
|
@@ -635,6 +1320,13 @@ export declare class EditorView extends Disposable {
|
|
|
635
1320
|
* have `pointer-events: none`, so the hit-test sees through them.
|
|
636
1321
|
*/
|
|
637
1322
|
isPointInContent(point: Point2D): boolean;
|
|
1323
|
+
/**
|
|
1324
|
+
* Whether `node` sits inside the rendered source text — the region whose
|
|
1325
|
+
* selection this editor paints itself from `model.selection`. Overlays
|
|
1326
|
+
* anchored beside the text (comment widgets and the like) are *not* part of
|
|
1327
|
+
* it and keep their own native selection behaviour.
|
|
1328
|
+
*/
|
|
1329
|
+
containsRenderedContent(node: Node | null | undefined): boolean;
|
|
638
1330
|
private readonly _renderAutorun;
|
|
639
1331
|
/** Current mounted blocks, or empty before the first render. */
|
|
640
1332
|
private get _blocks();
|
|
@@ -644,6 +1336,15 @@ export declare class EditorView extends Disposable {
|
|
|
644
1336
|
* is not read here, so there is no feedback loop into the render autorun.
|
|
645
1337
|
*/
|
|
646
1338
|
private _publishMeasurements;
|
|
1339
|
+
/**
|
|
1340
|
+
* Paint the diff highlights via the CSS Custom Highlight API: green over the
|
|
1341
|
+
* inserted/changed modified ranges (mapped on the document's own DOM), and
|
|
1342
|
+
* red over each {@link DiffDecorationViewNode}'s deleted ranges (mapped on
|
|
1343
|
+
* the decoration's own subtree). No DOM is mutated, so reconciliation and
|
|
1344
|
+
* editing are unaffected.
|
|
1345
|
+
*/
|
|
1346
|
+
private _paintDiff;
|
|
1347
|
+
private _clearDiff;
|
|
647
1348
|
}
|
|
648
1349
|
|
|
649
1350
|
export declare interface EditorViewOptions extends BlockViewOptions {
|
|
@@ -654,6 +1355,12 @@ export declare interface EditorViewOptions extends BlockViewOptions {
|
|
|
654
1355
|
* only) unless a theme class is supplied.
|
|
655
1356
|
*/
|
|
656
1357
|
readonly classNames?: readonly string[];
|
|
1358
|
+
/**
|
|
1359
|
+
* Whether to render the sticky edit/read-only toggle at the top-right edge
|
|
1360
|
+
* of the content. Defaults to `true`; set to `false` to omit it (e.g. in
|
|
1361
|
+
* fixtures that focus on selection rendering).
|
|
1362
|
+
*/
|
|
1363
|
+
readonly showReadonlyToggle?: boolean;
|
|
657
1364
|
/**
|
|
658
1365
|
* Controls "limited width mode". The observable yields the maximum content
|
|
659
1366
|
* width in pixels, or `undefined` to let the content fill the available
|
|
@@ -664,6 +1371,14 @@ export declare interface EditorViewOptions extends BlockViewOptions {
|
|
|
664
1371
|
* root ({@link element}) always spans the full available width.
|
|
665
1372
|
*/
|
|
666
1373
|
readonly limitedWidth?: IObservable<number | undefined>;
|
|
1374
|
+
/**
|
|
1375
|
+
* Diff mode only: render every read-only original decoration in active
|
|
1376
|
+
* (source) form, so even whole-block removals expose their markdown markers
|
|
1377
|
+
* as real text. Used by the diff-coverage fixture to verify that every
|
|
1378
|
+
* changed original character is rendered somewhere; off in normal use, where
|
|
1379
|
+
* whole removals show a clean solid band.
|
|
1380
|
+
*/
|
|
1381
|
+
readonly diffDecorationsActive?: boolean;
|
|
667
1382
|
}
|
|
668
1383
|
|
|
669
1384
|
export declare class EmphasisAstNode extends AstNode {
|
|
@@ -690,14 +1405,18 @@ declare class EmphasisViewData {
|
|
|
690
1405
|
*/
|
|
691
1406
|
export declare function findNodeOffsetById(root: AstNode, target: AstNode): number | undefined;
|
|
692
1407
|
|
|
693
|
-
export declare function findWordAt(text: string, offset: number): {
|
|
1408
|
+
export declare function findWordAt(text: string, offset: number, config?: WordNavigationConfig): {
|
|
694
1409
|
start: number;
|
|
695
1410
|
end: number;
|
|
696
1411
|
};
|
|
697
1412
|
|
|
698
|
-
export declare function findWordBoundaryLeft(text: string, offset: number): number;
|
|
1413
|
+
export declare function findWordBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
1414
|
+
|
|
1415
|
+
export declare function findWordBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
699
1416
|
|
|
700
|
-
export declare function
|
|
1417
|
+
export declare function findWordDeleteBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
1418
|
+
|
|
1419
|
+
export declare function findWordDeleteBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
701
1420
|
|
|
702
1421
|
export declare function getAnnotatedSource(node: AstNode, source: string, offset?: number): string;
|
|
703
1422
|
|
|
@@ -731,6 +1450,29 @@ declare class GlueViewData {
|
|
|
731
1450
|
decorateNewline: boolean);
|
|
732
1451
|
}
|
|
733
1452
|
|
|
1453
|
+
/**
|
|
1454
|
+
* A single gutter marker: a source {@link OffsetRange} tagged with a
|
|
1455
|
+
* {@link GutterMarkerType}. The view resolves the range to the visual lines it
|
|
1456
|
+
* covers and paints a bar (or, for `deleted`, a wedge at the range position) in
|
|
1457
|
+
* the left gutter.
|
|
1458
|
+
*
|
|
1459
|
+
* A `deleted` marker is normally an empty range (`range.isEmpty`) sitting at the
|
|
1460
|
+
* boundary where the removed text used to be — there is nothing left to span,
|
|
1461
|
+
* so it is drawn as a caret between lines rather than a bar.
|
|
1462
|
+
*/
|
|
1463
|
+
export declare interface GutterMarker {
|
|
1464
|
+
readonly range: OffsetRange;
|
|
1465
|
+
readonly type: GutterMarkerType;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
/**
|
|
1469
|
+
* The kind of change a gutter marker represents, mirroring the three states a
|
|
1470
|
+
* source-control diff distinguishes (the git change markers in the editor
|
|
1471
|
+
* gutter): a freshly inserted region, an edited region, and a point where
|
|
1472
|
+
* content was removed.
|
|
1473
|
+
*/
|
|
1474
|
+
export declare type GutterMarkerType = 'added' | 'modified' | 'deleted';
|
|
1475
|
+
|
|
734
1476
|
export declare class HeadingAstNode extends BlockAstNodeBase {
|
|
735
1477
|
readonly level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
736
1478
|
readonly marker: MarkerAstNode;
|
|
@@ -751,6 +1493,10 @@ declare class HeadingViewData {
|
|
|
751
1493
|
constructor(ast: HeadingAstNode, content: readonly AnyViewData[]);
|
|
752
1494
|
}
|
|
753
1495
|
|
|
1496
|
+
export declare function hiddenCursorRanges(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number): readonly OffsetRange[];
|
|
1497
|
+
|
|
1498
|
+
declare type HistoryKeyboardAction = 'undo' | 'redo';
|
|
1499
|
+
|
|
754
1500
|
/**
|
|
755
1501
|
* The editor operations a clipboard strategy drives. The strategy never
|
|
756
1502
|
* touches the model or the DOM directly — it asks through this seam, so the
|
|
@@ -787,6 +1533,9 @@ export declare interface IClipboardStrategy {
|
|
|
787
1533
|
connect(context: IClipboardContext): IDisposable;
|
|
788
1534
|
}
|
|
789
1535
|
|
|
1536
|
+
/** A live rendering of a {@link CommentsModel}. Dispose to unmount it. */
|
|
1537
|
+
export declare type ICommentsPresenter = IDisposable;
|
|
1538
|
+
|
|
790
1539
|
/** The Monarch language definitions the default highlighter wires up. */
|
|
791
1540
|
export declare interface IDefaultMonarchGrammars {
|
|
792
1541
|
typescript: unknown;
|
|
@@ -798,6 +1547,71 @@ export declare interface IDefaultMonarchGrammars {
|
|
|
798
1547
|
shell: unknown;
|
|
799
1548
|
}
|
|
800
1549
|
|
|
1550
|
+
/**
|
|
1551
|
+
* A live editor embedded in place of a fenced code block's *rendered* form.
|
|
1552
|
+
*
|
|
1553
|
+
* This is the internal seam between the block view and a concrete embedded
|
|
1554
|
+
* editor (e.g. an `<iframe>` speaking the web-editor protocol). The block view
|
|
1555
|
+
* only speaks string edits: it pushes the block's content down via
|
|
1556
|
+
* {@link setContent} and receives the editor's own changes back through
|
|
1557
|
+
* {@link onEdit} (set by the block view on each (re)construction, so it always
|
|
1558
|
+
* routes to the current AST node). The concrete implementation owns its DOM,
|
|
1559
|
+
* transport, and lifecycle.
|
|
1560
|
+
*
|
|
1561
|
+
* A single instance is adopted across re-renders (like the highlighter session)
|
|
1562
|
+
* so the underlying editor keeps its state across edits — see
|
|
1563
|
+
* {@link CodeBlockViewNode}.
|
|
1564
|
+
*/
|
|
1565
|
+
declare interface IEmbeddedCodeEditor {
|
|
1566
|
+
/** The element mounted as the block's rendered form. */
|
|
1567
|
+
readonly element: HTMLElement;
|
|
1568
|
+
/**
|
|
1569
|
+
* Document → editor. The block's content changed (from any source). Must be
|
|
1570
|
+
* idempotent: pushing the content the editor already holds is a no-op, which
|
|
1571
|
+
* is how edits the editor itself originated are prevented from echoing back.
|
|
1572
|
+
*/
|
|
1573
|
+
setContent(content: string): void;
|
|
1574
|
+
/**
|
|
1575
|
+
* Optional synchronous height (px) to reserve for `content` *before* the
|
|
1576
|
+
* editor has laid out. Return `undefined` to let the editor size itself
|
|
1577
|
+
* (the implementation may report its real height later). Lets a registration
|
|
1578
|
+
* avoid a layout jump when it can cheaply estimate the size from content.
|
|
1579
|
+
*/
|
|
1580
|
+
estimateHeight?(content: string): number | undefined;
|
|
1581
|
+
/**
|
|
1582
|
+
* Editor → document. Set by the block view on every (re)construction to
|
|
1583
|
+
* route the editor's own edits, expressed in the block's *content*
|
|
1584
|
+
* coordinates, to the current AST node.
|
|
1585
|
+
*/
|
|
1586
|
+
onEdit?: (edit: StringEdit) => void;
|
|
1587
|
+
dispose(): void;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
/** Creates an {@link IEmbeddedCodeEditor} for a fenced block, or opts out. */
|
|
1591
|
+
declare interface IEmbeddedCodeEditorFactory {
|
|
1592
|
+
/**
|
|
1593
|
+
* Return an editor for a fenced block of `language`, or `undefined` to fall
|
|
1594
|
+
* back to the default (highlighting / {@link BlockViewOptions.renderCustomCodeBlock}).
|
|
1595
|
+
*/
|
|
1596
|
+
create(language: string, initialContent: string): IEmbeddedCodeEditor | undefined;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* Routes undo and redo to whatever owns the document's history: the editor
|
|
1601
|
+
* itself on a standalone page, or the enclosing document in a host like
|
|
1602
|
+
* VS Code.
|
|
1603
|
+
*/
|
|
1604
|
+
export declare interface IHistoryStrategy {
|
|
1605
|
+
undo(): void;
|
|
1606
|
+
redo(): void;
|
|
1607
|
+
/**
|
|
1608
|
+
* Invoked around each source mutation so the strategy can record it.
|
|
1609
|
+
* Implemented only by strategies that build their own history; a host that
|
|
1610
|
+
* forwards edits to a VS Code `TextDocument` lets it record them instead.
|
|
1611
|
+
*/
|
|
1612
|
+
record?(operation: () => void, edit?: StringEdit): void;
|
|
1613
|
+
}
|
|
1614
|
+
|
|
801
1615
|
export declare class ImageAstNode extends AstNode {
|
|
802
1616
|
readonly alt: string;
|
|
803
1617
|
readonly url: string;
|
|
@@ -881,6 +1695,21 @@ export declare const insertLineBreak: EditCommand;
|
|
|
881
1695
|
|
|
882
1696
|
export declare const insertParagraph: EditCommand;
|
|
883
1697
|
|
|
1698
|
+
/**
|
|
1699
|
+
* Context-aware Enter. The behaviour is chosen from the active block:
|
|
1700
|
+
* - paragraph / heading / thematic break — the "rich text" thing: at the
|
|
1701
|
+
* block's end arm a transient empty paragraph (see {@link SmartEnterResult});
|
|
1702
|
+
* elsewhere split into two paragraphs (`\n\n`).
|
|
1703
|
+
* - code block — insert a newline that preserves the current line's indentation,
|
|
1704
|
+
* staying inside the fence.
|
|
1705
|
+
* - block quote — continue the quote (`\n> `); an empty quote line exits it.
|
|
1706
|
+
* - list — continue the list with the next marker (incrementing ordered
|
|
1707
|
+
* numbers, re-emitting task checkboxes); an empty item exits the list.
|
|
1708
|
+
* A non-collapsed selection, or any other block, falls back to a plain soft line
|
|
1709
|
+
* break, preserving today's behaviour.
|
|
1710
|
+
*/
|
|
1711
|
+
export declare const insertSmartEnter: (ctx: CursorCommandContext) => SmartEnterResult;
|
|
1712
|
+
|
|
884
1713
|
export declare function insertText(text: string): EditCommand;
|
|
885
1714
|
|
|
886
1715
|
/**
|
|
@@ -922,6 +1751,29 @@ export declare interface ISyntaxHighlighterDocument extends IDisposable {
|
|
|
922
1751
|
readonly snapshot: IObservableWithChange<ISyntaxHighlightedSnapshot, LengthEdit>;
|
|
923
1752
|
}
|
|
924
1753
|
|
|
1754
|
+
export declare interface KeyboardBinding {
|
|
1755
|
+
readonly key: string;
|
|
1756
|
+
readonly modifiers?: KeyboardModifiers;
|
|
1757
|
+
readonly platforms?: readonly KeyboardPlatform[];
|
|
1758
|
+
readonly action: EditorKeyboardAction;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
export declare interface KeyboardModifiers {
|
|
1762
|
+
readonly shift?: boolean;
|
|
1763
|
+
readonly alt?: boolean;
|
|
1764
|
+
readonly ctrl?: boolean;
|
|
1765
|
+
readonly meta?: boolean;
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
export declare type KeyboardPlatform = 'macos' | 'windows' | 'linux';
|
|
1769
|
+
|
|
1770
|
+
export declare interface KeyboardProfile {
|
|
1771
|
+
/**
|
|
1772
|
+
* Bindings in priority order. The first exact key/modifier/platform match wins.
|
|
1773
|
+
*/
|
|
1774
|
+
readonly bindings: readonly KeyboardBinding[];
|
|
1775
|
+
}
|
|
1776
|
+
|
|
925
1777
|
declare abstract class LeafAstNode extends AstNode {
|
|
926
1778
|
abstract readonly content: string;
|
|
927
1779
|
get children(): readonly AstNode[];
|
|
@@ -1034,6 +1886,32 @@ declare class ListViewData {
|
|
|
1034
1886
|
constructor(ast: ListAstNode, content: readonly AnyViewData[]);
|
|
1035
1887
|
}
|
|
1036
1888
|
|
|
1889
|
+
/**
|
|
1890
|
+
* Compact in-memory history for editors that hold the only copy of the
|
|
1891
|
+
* document, such as a standalone browser page. Where the surrounding host
|
|
1892
|
+
* already records history — a VS Code `TextDocument` — forward to that
|
|
1893
|
+
* instead.
|
|
1894
|
+
*/
|
|
1895
|
+
export declare class LocalHistoryStrategy implements IHistoryStrategy {
|
|
1896
|
+
private readonly _model;
|
|
1897
|
+
private readonly _past;
|
|
1898
|
+
private readonly _future;
|
|
1899
|
+
/**
|
|
1900
|
+
* The source text as of the last change this strategy recorded or applied.
|
|
1901
|
+
* Any other value means the document was replaced behind its back, so the
|
|
1902
|
+
* stored edits no longer line up and must be discarded rather than applied.
|
|
1903
|
+
*/
|
|
1904
|
+
private _lastKnownText;
|
|
1905
|
+
constructor(_model: EditorModel);
|
|
1906
|
+
record(operation: () => void, edit?: StringEdit): void;
|
|
1907
|
+
undo(): void;
|
|
1908
|
+
redo(): void;
|
|
1909
|
+
/** The entry on top of `stack`, or `undefined` when it cannot be applied. */
|
|
1910
|
+
private _peekApplicable;
|
|
1911
|
+
private _apply;
|
|
1912
|
+
private _clear;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1037
1915
|
/**
|
|
1038
1916
|
* Parses markdown into a {@link DocumentAstNode}.
|
|
1039
1917
|
*
|
|
@@ -1140,8 +2018,8 @@ export declare class MeasuredLayoutDebugRendering {
|
|
|
1140
2018
|
* Exposes two DOM nodes the caller can place independently:
|
|
1141
2019
|
*
|
|
1142
2020
|
* - {@link overlayElement} — absolutely positioned; the caller mounts it
|
|
1143
|
-
* inside the editor
|
|
1144
|
-
*
|
|
2021
|
+
* inside the editor overlay container so dashed line-bands and run-boxes
|
|
2022
|
+
* share the measured editor-local coordinates.
|
|
1145
2023
|
* - {@link infoElement} — block-flow; the caller mounts it as a sibling
|
|
1146
2024
|
* *below* the editor. Contains the per-block summary table that used
|
|
1147
2025
|
* to live on the overlay.
|
|
@@ -1152,7 +2030,6 @@ export declare class MeasuredLayoutDebugRendering {
|
|
|
1152
2030
|
* the derived subscribed.
|
|
1153
2031
|
*/
|
|
1154
2032
|
export declare class MeasuredLayoutDebugView extends Disposable {
|
|
1155
|
-
private readonly _overlayParent;
|
|
1156
2033
|
readonly overlayElement: HTMLElement;
|
|
1157
2034
|
readonly infoElement: HTMLElement;
|
|
1158
2035
|
readonly rendering: IObservable<MeasuredLayoutDebugRendering>;
|
|
@@ -1165,6 +2042,7 @@ export declare class MeasuredLayoutDebugView extends Disposable {
|
|
|
1165
2042
|
|
|
1166
2043
|
export declare interface MeasuredLayoutDebugViewOptions {
|
|
1167
2044
|
readonly model: MeasuredLayoutModel;
|
|
2045
|
+
readonly coordinateSpace: EditorCoordinateSpace;
|
|
1168
2046
|
/**
|
|
1169
2047
|
* DEBUG ONLY. Maps an absolute source offset to a fill color for that
|
|
1170
2048
|
* character's glyph rect. The fixture passes the same function to the
|
|
@@ -1199,10 +2077,9 @@ export declare interface MeasuredLayoutDebugViewOptions {
|
|
|
1199
2077
|
export declare class MeasuredLayoutModel {
|
|
1200
2078
|
readonly measurements: ISettableObservable<readonly BlockMeasurement[], void>;
|
|
1201
2079
|
/**
|
|
1202
|
-
* Concatenated visual line map across all mounted blocks.
|
|
1203
|
-
*
|
|
1204
|
-
*
|
|
1205
|
-
* concatenation is well-formed without re-sorting.
|
|
2080
|
+
* Concatenated visual line map across all mounted blocks. Every per-block
|
|
2081
|
+
* map uses the same editor-local coordinate space, so concatenation is
|
|
2082
|
+
* well-formed without translation or re-sorting.
|
|
1206
2083
|
*/
|
|
1207
2084
|
readonly visualLineMap: IObservableWithChange<VisualLineMap, void>;
|
|
1208
2085
|
}
|
|
@@ -1244,14 +2121,25 @@ export declare class NativeClipboardStrategy implements IClipboardStrategy {
|
|
|
1244
2121
|
connect(context: IClipboardContext): IDisposable;
|
|
1245
2122
|
}
|
|
1246
2123
|
|
|
2124
|
+
declare interface NestedItem {
|
|
2125
|
+
readonly kind: 'nested';
|
|
2126
|
+
readonly original: AstNode;
|
|
2127
|
+
readonly originalStart: number;
|
|
2128
|
+
readonly modified: AstNode;
|
|
2129
|
+
readonly modifiedStart: number;
|
|
2130
|
+
readonly children: readonly DiffItem[];
|
|
2131
|
+
}
|
|
2132
|
+
|
|
1247
2133
|
/**
|
|
1248
2134
|
* Move the cursor one position left or right, skipping over hidden marker
|
|
1249
2135
|
* ranges in inactive blocks (and inactive items of an active list).
|
|
1250
2136
|
*/
|
|
1251
|
-
export declare function nextCursorPosition(doc: DocumentAstNode,
|
|
2137
|
+
export declare function nextCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, direction: 'left' | 'right'): number;
|
|
1252
2138
|
|
|
1253
2139
|
declare const NO_ACTIVE_BLOCKS: unique symbol;
|
|
1254
2140
|
|
|
2141
|
+
export declare function normalizeCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, target: number, direction: 'left' | 'right', includeHiddenRangeBoundary?: boolean): number;
|
|
2142
|
+
|
|
1255
2143
|
export declare class OffsetRange {
|
|
1256
2144
|
readonly start: number;
|
|
1257
2145
|
readonly endExclusive: number;
|
|
@@ -1297,7 +2185,48 @@ declare class ParagraphViewData {
|
|
|
1297
2185
|
}
|
|
1298
2186
|
|
|
1299
2187
|
/**
|
|
1300
|
-
*
|
|
2188
|
+
* A *transient* editing state: the empty paragraph the user conjured by
|
|
2189
|
+
* pressing Enter at the end of a paragraph. Markdown has no empty-paragraph
|
|
2190
|
+
* node, so this never lives in {@link EditorModel['sourceText']} or the parsed
|
|
2191
|
+
* {@link EditorModel.document} — it is pure edit intent that the view renders
|
|
2192
|
+
* as a synthetic blank line and that the controller either *materializes* (the
|
|
2193
|
+
* user types) or *cancels* (the user navigates away / backspaces).
|
|
2194
|
+
*/
|
|
2195
|
+
declare interface PendingParagraph {
|
|
2196
|
+
/** The paragraph the blank line is rendered directly after. */
|
|
2197
|
+
readonly anchorBlock: BlockAstNode;
|
|
2198
|
+
/**
|
|
2199
|
+
* Source region rewritten when the pending paragraph is materialized — the
|
|
2200
|
+
* gap between {@link anchorBlock}'s text and whatever follows it.
|
|
2201
|
+
*/
|
|
2202
|
+
readonly replaceRange: OffsetRange;
|
|
2203
|
+
/** Whether {@link replaceRange} ends at the end of the document. */
|
|
2204
|
+
readonly atEof: boolean;
|
|
2205
|
+
/**
|
|
2206
|
+
* A throwaway AST node that exists only to give the synthetic view child a
|
|
2207
|
+
* stable identity across render frames (the view pairs nodes by `ast.id`).
|
|
2208
|
+
* It is never part of {@link document}.
|
|
2209
|
+
*/
|
|
2210
|
+
readonly syntheticAst: ParagraphAstNode;
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
/**
|
|
2214
|
+
* View-data for the transient empty paragraph (see `PendingParagraph` in the
|
|
2215
|
+
* model). It carries only the throwaway {@link ParagraphAstNode} that gives the
|
|
2216
|
+
* rendered blank line a stable identity across frames; it has no content and is
|
|
2217
|
+
* never measured or part of the selection geometry — the caret is positioned
|
|
2218
|
+
* over it via a dedicated rect, not via the visual-line map.
|
|
2219
|
+
*/
|
|
2220
|
+
declare class PendingParagraphViewData {
|
|
2221
|
+
readonly ast: ParagraphAstNode;
|
|
2222
|
+
readonly kind = "pendingParagraph";
|
|
2223
|
+
constructor(ast: ParagraphAstNode);
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
/**
|
|
2227
|
+
* Immutable point in a caller-defined 2D CSS-pixel coordinate space.
|
|
2228
|
+
* Coordinate-owning APIs must document whether values are viewport-client or
|
|
2229
|
+
* editor-local; values from different spaces must not be mixed.
|
|
1301
2230
|
*/
|
|
1302
2231
|
export declare class Point2D {
|
|
1303
2232
|
readonly x: number;
|
|
@@ -1308,8 +2237,8 @@ export declare class Point2D {
|
|
|
1308
2237
|
}
|
|
1309
2238
|
|
|
1310
2239
|
/**
|
|
1311
|
-
* Immutable axis-aligned rectangle in
|
|
1312
|
-
*
|
|
2240
|
+
* Immutable axis-aligned rectangle in a caller-defined 2D CSS-pixel coordinate
|
|
2241
|
+
* space. `x`/`y` is the top-left corner, growing right/down.
|
|
1313
2242
|
*
|
|
1314
2243
|
* Half-open in both dimensions: `right` and `bottom` are excluded.
|
|
1315
2244
|
*/
|
|
@@ -1335,6 +2264,23 @@ export declare class Rect2D {
|
|
|
1335
2264
|
translate(dx: number, dy: number): Rect2D;
|
|
1336
2265
|
}
|
|
1337
2266
|
|
|
2267
|
+
declare interface RemovedItem {
|
|
2268
|
+
readonly kind: 'removed';
|
|
2269
|
+
readonly node: AstNode;
|
|
2270
|
+
readonly originalStart: number;
|
|
2271
|
+
readonly deletedLocal: readonly AnnotatedRange[];
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
declare interface ReplacedItem {
|
|
2275
|
+
readonly kind: 'replaced';
|
|
2276
|
+
readonly original: AstNode;
|
|
2277
|
+
readonly originalStart: number;
|
|
2278
|
+
readonly modified: AstNode;
|
|
2279
|
+
readonly modifiedStart: number;
|
|
2280
|
+
readonly insertedLocal: readonly AnnotatedRange[];
|
|
2281
|
+
readonly deletedLocal: readonly AnnotatedRange[];
|
|
2282
|
+
}
|
|
2283
|
+
|
|
1338
2284
|
export declare const selectAll: SelectionCommand;
|
|
1339
2285
|
|
|
1340
2286
|
export declare function selectBlock(ctx: CursorCommandContext, blockRange: OffsetRange): Selection_2;
|
|
@@ -1360,8 +2306,13 @@ export { Selection_2 as Selection }
|
|
|
1360
2306
|
export declare interface SelectionBlock {
|
|
1361
2307
|
readonly block: BlockAstNode;
|
|
1362
2308
|
readonly absoluteStart: number;
|
|
1363
|
-
|
|
1364
|
-
readonly
|
|
2309
|
+
/** Block border box in editor-local coordinates. */
|
|
2310
|
+
readonly rect: Rect2D;
|
|
2311
|
+
/** Visible horizontal padding-box bounds for a scrolling block. */
|
|
2312
|
+
readonly viewportClip: {
|
|
2313
|
+
readonly left: number;
|
|
2314
|
+
readonly right: number;
|
|
2315
|
+
} | undefined;
|
|
1365
2316
|
}
|
|
1366
2317
|
|
|
1367
2318
|
export declare type SelectionCommand = (ctx: CursorCommandContext, offset: SourceOffset) => Selection_2;
|
|
@@ -1393,11 +2344,10 @@ export declare interface SelectionRect {
|
|
|
1393
2344
|
* envelope shape used by IDE selection rendering.
|
|
1394
2345
|
*/
|
|
1395
2346
|
export declare class SelectionView extends Disposable {
|
|
1396
|
-
private readonly _parent;
|
|
1397
2347
|
readonly element: SVGSVGElement;
|
|
1398
2348
|
readonly rendering: IObservable<SelectionViewRendering>;
|
|
1399
2349
|
private readonly _path;
|
|
1400
|
-
constructor(
|
|
2350
|
+
constructor(options: SelectionViewOptions);
|
|
1401
2351
|
}
|
|
1402
2352
|
|
|
1403
2353
|
export declare interface SelectionViewOptions {
|
|
@@ -1413,6 +2363,25 @@ export declare class SelectionViewRendering {
|
|
|
1413
2363
|
|
|
1414
2364
|
export declare const selectWord: SelectionCommand;
|
|
1415
2365
|
|
|
2366
|
+
/**
|
|
2367
|
+
* The outcome of {@link insertSmartEnter}: either a concrete source edit (the
|
|
2368
|
+
* ordinary cases), or a request to arm a transient empty paragraph (Enter at
|
|
2369
|
+
* the very end of a paragraph), which the controller turns into
|
|
2370
|
+
* {@link EditorModel.armPendingParagraph} rather than a source edit. Modelling
|
|
2371
|
+
* the empty paragraph as state instead of source keeps the document valid
|
|
2372
|
+
* Markdown — which has no empty-paragraph node — until the user actually types.
|
|
2373
|
+
*/
|
|
2374
|
+
export declare type SmartEnterResult = {
|
|
2375
|
+
readonly kind: 'edit';
|
|
2376
|
+
readonly edit: StringEdit;
|
|
2377
|
+
readonly selection: Selection_2;
|
|
2378
|
+
} | {
|
|
2379
|
+
readonly kind: 'pending';
|
|
2380
|
+
readonly anchorBlock: BlockAstNode;
|
|
2381
|
+
readonly replaceRange: OffsetRange;
|
|
2382
|
+
readonly atEof: boolean;
|
|
2383
|
+
};
|
|
2384
|
+
|
|
1416
2385
|
/**
|
|
1417
2386
|
* A run of {@link Token}s together with the exact {@link OffsetRange} they
|
|
1418
2387
|
* cover.
|
|
@@ -1428,6 +2397,29 @@ export declare interface SnapshotTokens {
|
|
|
1428
2397
|
|
|
1429
2398
|
export declare type SourceOffset = number;
|
|
1430
2399
|
|
|
2400
|
+
export declare abstract class StackedCommentsPresenter extends Disposable implements ICommentsPresenter {
|
|
2401
|
+
protected readonly model: CommentsModel;
|
|
2402
|
+
protected readonly view: EditorView;
|
|
2403
|
+
protected readonly context?: CommentsPresenterContext | undefined;
|
|
2404
|
+
private readonly _layer;
|
|
2405
|
+
private readonly _entries;
|
|
2406
|
+
private _order;
|
|
2407
|
+
private _pendingRevealCommentId;
|
|
2408
|
+
constructor(model: CommentsModel, view: EditorView, context?: CommentsPresenterContext | undefined);
|
|
2409
|
+
/** Build the card DOM for a comment. Called once per new comment. */
|
|
2410
|
+
protected abstract createWidget(comment: Comment_2): StackWidget;
|
|
2411
|
+
revealComment(id: string): void;
|
|
2412
|
+
private _reconcile;
|
|
2413
|
+
private _relayout;
|
|
2414
|
+
private _revealPendingComment;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
/** The minimal widget contract a subclass must produce. */
|
|
2418
|
+
export declare interface StackWidget {
|
|
2419
|
+
readonly element: HTMLElement;
|
|
2420
|
+
dispose(): void;
|
|
2421
|
+
}
|
|
2422
|
+
|
|
1431
2423
|
export declare class StrikethroughAstNode extends AstNode {
|
|
1432
2424
|
readonly openMarker: MarkerAstNode;
|
|
1433
2425
|
readonly content: readonly (InlineAstNode | GlueAstNode)[];
|
|
@@ -1470,6 +2462,11 @@ export declare class StringReplacement {
|
|
|
1470
2462
|
constructor(replaceRange: OffsetRange, newText: string);
|
|
1471
2463
|
get isEmpty(): boolean;
|
|
1472
2464
|
equals(other: StringReplacement): boolean;
|
|
2465
|
+
/**
|
|
2466
|
+
* Narrows this replacement to the span that actually changes, by trimming
|
|
2467
|
+
* the prefix and suffix it shares with the text it replaces in `source`.
|
|
2468
|
+
*/
|
|
2469
|
+
removeCommonSuffixPrefix(source: string): StringReplacement;
|
|
1473
2470
|
toString(): string;
|
|
1474
2471
|
}
|
|
1475
2472
|
|
|
@@ -1632,6 +2629,47 @@ export declare class Token {
|
|
|
1632
2629
|
className: string | undefined);
|
|
1633
2630
|
}
|
|
1634
2631
|
|
|
2632
|
+
declare interface UnchangedItem {
|
|
2633
|
+
readonly kind: 'unchanged';
|
|
2634
|
+
/** The modified-side node (identical in content to the original). */
|
|
2635
|
+
readonly node: AstNode;
|
|
2636
|
+
readonly modifiedStart: number;
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
/**
|
|
2640
|
+
* A block whose token type the parser does not understand (a setext heading, a
|
|
2641
|
+
* frontmatter fence, any future/extension construct). Rather than dropping the
|
|
2642
|
+
* span — which would demote its text to invisible glue — the parser captures the
|
|
2643
|
+
* whole source range verbatim as a single {@link MarkerAstNode} of kind
|
|
2644
|
+
* `content` and records the originating micromark {@link tokenType}, so the view
|
|
2645
|
+
* can render it as raw, editable text with an "unhandled" affordance. Offsets
|
|
2646
|
+
* stay sound: `content` tiles the block's full source span exactly.
|
|
2647
|
+
*/
|
|
2648
|
+
declare class UnhandledBlockAstNode extends BlockAstNodeBase {
|
|
2649
|
+
readonly tokenType: string;
|
|
2650
|
+
readonly content: readonly (MarkerAstNode | GlueAstNode)[];
|
|
2651
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
2652
|
+
readonly kind = "unhandledBlock";
|
|
2653
|
+
constructor(tokenType: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
2654
|
+
get children(): readonly AstNode[];
|
|
2655
|
+
get code(): MarkerAstNode | undefined;
|
|
2656
|
+
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
2657
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): UnhandledBlockAstNode;
|
|
2658
|
+
protected _localEquals(o: this): boolean;
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
/**
|
|
2662
|
+
* View-data for an {@link UnhandledBlockAstNode}. It has no active/inactive
|
|
2663
|
+
* split — the raw source *is* both the source and the rendered form — so it
|
|
2664
|
+
* carries no `showMarkup` flag; the renderer always shows the verbatim text.
|
|
2665
|
+
*/
|
|
2666
|
+
declare class UnhandledBlockViewData {
|
|
2667
|
+
readonly ast: UnhandledBlockAstNode;
|
|
2668
|
+
readonly content: readonly AnyViewData[];
|
|
2669
|
+
readonly kind = "unhandledBlock";
|
|
2670
|
+
constructor(ast: UnhandledBlockAstNode, content: readonly AnyViewData[]);
|
|
2671
|
+
}
|
|
2672
|
+
|
|
1635
2673
|
/**
|
|
1636
2674
|
* Immutable view of an AST node. Pairs `ast` with its rendered `dom` and a
|
|
1637
2675
|
* mirror of `ast.children` as ViewNode children. Source offsets are NEVER
|
|
@@ -1696,10 +2734,12 @@ export declare class ViewNode extends Disposable {
|
|
|
1696
2734
|
/**
|
|
1697
2735
|
* Map a DOM hit that lands on THIS node's own representation into a source
|
|
1698
2736
|
* range in this node's local space `[0, ast.length)`. Polymorphic: a text
|
|
1699
|
-
* leaf maps the caret offset 1:1
|
|
1700
|
-
* an image, a hidden marker)
|
|
1701
|
-
*
|
|
1702
|
-
*
|
|
2737
|
+
* leaf maps the caret offset 1:1. For an element hit — an element-only node
|
|
2738
|
+
* (KaTeX math, `<hr>`, an image, a hidden marker) or a wrapper/container
|
|
2739
|
+
* element — the platform reports a child-index offset, not a text caret, so
|
|
2740
|
+
* there is no internal mapping to honour: it snaps to the node's nearer
|
|
2741
|
+
* edge, `offset 0` (the "before" side) → start, any `offset >= 1` (the
|
|
2742
|
+
* "after" side) → end. Subclasses may override for finer control.
|
|
1703
2743
|
*/
|
|
1704
2744
|
getLocalSourceRange(pos: DomPosition): OffsetRange;
|
|
1705
2745
|
/**
|
|
@@ -1743,7 +2783,8 @@ export declare class VisualLine {
|
|
|
1743
2783
|
/**
|
|
1744
2784
|
* How `offset` relates to this line's runs:
|
|
1745
2785
|
* - `'covers'`: a run starts at or strictly contains the offset
|
|
1746
|
-
* (`start <= offset < endExclusive`)
|
|
2786
|
+
* (`start <= offset < endExclusive`), or a zero-length visual-line
|
|
2787
|
+
* anchor sits at the offset — the caret belongs on this line.
|
|
1747
2788
|
* - `'end'`: the offset is only some run's trailing boundary
|
|
1748
2789
|
* (`offset === endExclusive`) with no run covering it — a line-break
|
|
1749
2790
|
* boundary the caret should leave for the next line.
|
|
@@ -1756,23 +2797,37 @@ export declare class VisualLine {
|
|
|
1756
2797
|
*/
|
|
1757
2798
|
sourceDistanceTo(offset: SourceOffset): number;
|
|
1758
2799
|
/**
|
|
1759
|
-
* x of the caret position before `offset` on this line.
|
|
1760
|
-
*
|
|
1761
|
-
*
|
|
1762
|
-
*
|
|
2800
|
+
* x of the caret position before `offset` on this line.
|
|
2801
|
+
*
|
|
2802
|
+
* The runs tile the source but are stored in paint order, not sorted by
|
|
2803
|
+
* source offset (hidden-marker runs are appended last). So this scans all
|
|
2804
|
+
* runs rather than assuming any ordering:
|
|
2805
|
+
*
|
|
2806
|
+
* - If some run *covers* `offset`, its own geometry places the caret
|
|
2807
|
+
* (exact glyph boundary for text runs). In the active, markers-visible
|
|
2808
|
+
* form every offset is covered, so this branch keeps distinct offsets
|
|
2809
|
+
* distinct.
|
|
2810
|
+
* - Otherwise `offset` sits in a gap — a hidden inline marker such as the
|
|
2811
|
+
* `**` of `**bold**`, or before/after the painted text. It snaps to the
|
|
2812
|
+
* seam between the source-nearest runs on either side: the right edge of
|
|
2813
|
+
* the closest run ending at/before `offset`, else the left edge of the
|
|
2814
|
+
* closest run starting at/after it. A hidden marker collapses to zero
|
|
2815
|
+
* width, so both edges coincide at the seam.
|
|
1763
2816
|
*/
|
|
1764
2817
|
xAtOffset(offset: SourceOffset): number;
|
|
1765
2818
|
/**
|
|
1766
2819
|
* Snap `x` to the nearest offset on this line. If `x` falls inside a
|
|
1767
|
-
* run, the offset
|
|
1768
|
-
*
|
|
2820
|
+
* run, the run resolves the offset (exact glyph boundary for text runs,
|
|
2821
|
+
* nearer edge for source-less runs); otherwise it snaps to the closer
|
|
2822
|
+
* edge of the nearest run.
|
|
1769
2823
|
*/
|
|
1770
2824
|
offsetAtX(x: number): SourceOffset;
|
|
1771
2825
|
}
|
|
1772
2826
|
|
|
1773
2827
|
/**
|
|
1774
2828
|
* Geometry of the rendered document, as a map from source offsets to 2D
|
|
1775
|
-
* positions and back.
|
|
2829
|
+
* positions and back. All geometry is expressed in the editor overlay's local
|
|
2830
|
+
* CSS-pixel coordinate space.
|
|
1776
2831
|
*
|
|
1777
2832
|
* Structure (top to bottom):
|
|
1778
2833
|
*
|
|
@@ -1807,7 +2862,7 @@ export declare class VisualLineMap {
|
|
|
1807
2862
|
static measure(blockViews: readonly {
|
|
1808
2863
|
readonly absoluteStart: number;
|
|
1809
2864
|
readonly viewNode: ViewNode;
|
|
1810
|
-
}[]): VisualLineMap;
|
|
2865
|
+
}[], coordinateSpace: EditorCoordinateSpace, transform?: EditorCoordinateTransform): VisualLineMap;
|
|
1811
2866
|
constructor(lines: readonly VisualLine[]);
|
|
1812
2867
|
get lineCount(): number;
|
|
1813
2868
|
get isEmpty(): boolean;
|
|
@@ -1845,6 +2900,8 @@ export declare class VisualLineMap {
|
|
|
1845
2900
|
offsetAtPoint(point: Point2D): SourceOffset;
|
|
1846
2901
|
/** Snap `x` to the nearest offset on a specific line. */
|
|
1847
2902
|
offsetInLineAtX(lineIndex: number, x: number): SourceOffset;
|
|
2903
|
+
lineStartOffset(lineIndex: number): SourceOffset | undefined;
|
|
2904
|
+
lineEndOffset(lineIndex: number): SourceOffset | undefined;
|
|
1848
2905
|
}
|
|
1849
2906
|
|
|
1850
2907
|
/**
|
|
@@ -1853,14 +2910,22 @@ export declare class VisualLineMap {
|
|
|
1853
2910
|
* When constructed with a {@link VisualRunSource}, `xAtOffset` returns the
|
|
1854
2911
|
* pixel-exact x of the caret before character `offset` by measuring the
|
|
1855
2912
|
* prefix `[textNodeStart, textNodeStart + (offset - sourceStart))` with a
|
|
1856
|
-
* DOM `Range`.
|
|
1857
|
-
*
|
|
2913
|
+
* DOM `Range`.
|
|
2914
|
+
*
|
|
2915
|
+
* A source-less run has no per-offset geometry: it either represents an
|
|
2916
|
+
* element-only block (KaTeX math, a mermaid/custom diagram, an image, an
|
|
2917
|
+
* inactive `<hr>`) whose box does not correspond to source offsets, or a
|
|
2918
|
+
* hand-built run in a test. Either way it maps between offsets and x by
|
|
2919
|
+
* snapping to the nearer edge of {@link rect} rather than fabricating
|
|
2920
|
+
* interior positions.
|
|
1858
2921
|
*/
|
|
1859
2922
|
export declare class VisualRun {
|
|
1860
2923
|
readonly sourceRange: OffsetRange;
|
|
1861
2924
|
readonly rect: Rect2D;
|
|
1862
2925
|
readonly source?: VisualRunSource | undefined;
|
|
1863
|
-
|
|
2926
|
+
readonly isVisualLineAnchor: boolean;
|
|
2927
|
+
static visualLineAnchor(sourceOffset: SourceOffset, rect: Rect2D): VisualRun;
|
|
2928
|
+
constructor(sourceRange: OffsetRange, rect: Rect2D, source?: VisualRunSource | undefined, isVisualLineAnchor?: boolean);
|
|
1864
2929
|
get sourceStart(): SourceOffset;
|
|
1865
2930
|
get sourceEndExclusive(): SourceOffset;
|
|
1866
2931
|
get sourceLength(): number;
|
|
@@ -1872,19 +2937,36 @@ export declare class VisualRun {
|
|
|
1872
2937
|
|
|
1873
2938
|
/**
|
|
1874
2939
|
* The DOM source of a {@link VisualRun}. When set, `xAtOffset` and
|
|
1875
|
-
* `offsetAtX` measure exact glyph positions via `Range.getBoundingClientRect
|
|
1876
|
-
*
|
|
1877
|
-
*
|
|
1878
|
-
*
|
|
1879
|
-
* wrong character.
|
|
2940
|
+
* `offsetAtX` measure exact glyph positions via `Range.getBoundingClientRect`.
|
|
2941
|
+
* This matters for proportional fonts where character widths differ a lot
|
|
2942
|
+
* (e.g. `m` vs `i`): a caret placed by anything coarser than real glyph
|
|
2943
|
+
* measurement lands several pixels inside the wrong character.
|
|
1880
2944
|
*
|
|
1881
|
-
*
|
|
1882
|
-
*
|
|
2945
|
+
* A run without a source has no per-offset geometry, so it maps between
|
|
2946
|
+
* offsets and x by snapping to the nearer run edge. Real text runs always
|
|
2947
|
+
* carry a source; source-less runs are element-only blocks (see
|
|
2948
|
+
* {@link _appendElementBlockRun}) and hand-built runs in tests.
|
|
1883
2949
|
*/
|
|
1884
2950
|
declare interface VisualRunSource {
|
|
1885
2951
|
readonly textNode: Text;
|
|
1886
2952
|
/** Offset within `textNode.data` corresponding to `sourceRange.start`. */
|
|
1887
2953
|
readonly textNodeStart: number;
|
|
2954
|
+
readonly coordinateSpace: EditorCoordinateSpace;
|
|
2955
|
+
}
|
|
2956
|
+
|
|
2957
|
+
export declare const vscodeKeyboardProfile: KeyboardProfile;
|
|
2958
|
+
|
|
2959
|
+
export declare class VscodeStackedCommentsView extends StackedCommentsPresenter {
|
|
2960
|
+
protected createWidget(comment: Comment_2): StackWidget;
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
export declare class VsCodeV2CommentsView extends StackedCommentsPresenter {
|
|
2964
|
+
protected createWidget(comment: Comment_2): StackWidget;
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
export declare interface WordNavigationConfig {
|
|
2968
|
+
readonly wordSeparators: string;
|
|
2969
|
+
readonly wordSegmenterLocales: readonly string[];
|
|
1888
2970
|
}
|
|
1889
2971
|
|
|
1890
2972
|
export { }
|