@vscode/markdown-editor 0.0.2-2 → 0.0.2-21
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/index.d.ts +1000 -52
- package/dist/index.js +4005 -2074
- package/dist/index.js.map +1 -1
- package/dist/markdown-editor.css +1 -0
- package/dist/observables.js +79 -101
- package/dist/observables.js.map +1 -1
- package/dist/{runOnChange-owE1SMC0.js → runOnChange-CkxK2gSn.js} +191 -163
- package/dist/runOnChange-CkxK2gSn.js.map +1 -0
- package/dist/stringEdit-DzLs4E1d.js +177 -0
- package/dist/stringEdit-DzLs4E1d.js.map +1 -0
- package/dist/web-editors.d.ts +125 -0
- package/dist/web-editors.js +5185 -0
- package/dist/web-editors.js.map +1 -0
- package/package.json +36 -9
- package/src/contrib/comments/commentInput.css +150 -0
- package/src/contrib/comments/comments.css +129 -0
- package/src/contrib/commentsVscode/vscodeCommentWidgetV2.css +166 -0
- package/src/view/editor.css +526 -32
- package/src/view/themes/default.css +11 -3
- package/src/view/themes/github.css +12 -9
- package/src/view/themes/vscode-default.css +347 -0
- package/src/view/themes/vscode-github.css +349 -0
- package/dist/runOnChange-owE1SMC0.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;
|
|
@@ -31,7 +48,7 @@ export declare abstract class AstNode {
|
|
|
31
48
|
* instances — keeping this O(children), not O(subtree). Leaves have no
|
|
32
49
|
* children, so {@link _localEquals} is their whole comparison.
|
|
33
50
|
*/
|
|
34
|
-
|
|
51
|
+
equalsShallow(other: AstNode): boolean;
|
|
35
52
|
/** Compares only this node's own scalar fields (kind/length already match). */
|
|
36
53
|
protected _localEquals(_other: this): boolean;
|
|
37
54
|
/**
|
|
@@ -54,7 +71,40 @@ declare interface AstVisualizationNode {
|
|
|
54
71
|
children?: AstVisualizationNode[];
|
|
55
72
|
}
|
|
56
73
|
|
|
57
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Strategy for hosts that never deliver native clipboard events to the editor
|
|
76
|
+
* — most importantly VS Code webviews, whose preload calls `preventDefault()`
|
|
77
|
+
* on the Ctrl/Cmd+C/X/V keydowns, so no `copy`/`cut`/`paste` event is ever
|
|
78
|
+
* dispatched. Here the keystrokes are the only signal, so this strategy
|
|
79
|
+
* listens for them directly and drives the async {@link Clipboard} API
|
|
80
|
+
* (`navigator.clipboard`), which webviews are granted.
|
|
81
|
+
*
|
|
82
|
+
* Cut deletes synchronously once the text is captured; the clipboard write is
|
|
83
|
+
* fire-and-forget. Paste must wait for the async read before inserting.
|
|
84
|
+
*/
|
|
85
|
+
export declare class AsyncClipboardStrategy implements IClipboardStrategy {
|
|
86
|
+
private readonly _clipboard;
|
|
87
|
+
constructor(_clipboard?: Clipboard);
|
|
88
|
+
connect(context: IClipboardContext): IDisposable;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export declare type BlockAstNode = HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | ThematicBreakAstNode | BlockQuoteAstNode | ListAstNode | TableAstNode | UnhandledBlockAstNode;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* A block-level node. Every block may carry a {@link leadingTrivia} glue — the
|
|
95
|
+
* whitespace that precedes it on its own line (a nested list's indentation, the
|
|
96
|
+
* leading space of a continued paragraph). It is owned by the block it precedes
|
|
97
|
+
* (not the one it trails), so the view reveals it exactly when *this* block is
|
|
98
|
+
* active, and it tiles at the block's front: {@link children} prepends it to the
|
|
99
|
+
* block's own content while `content` stays the block's real payload.
|
|
100
|
+
*/
|
|
101
|
+
declare abstract class BlockAstNodeBase extends AstNode {
|
|
102
|
+
abstract readonly leadingTrivia?: GlueAstNode;
|
|
103
|
+
/** This block with its leading trivia replaced — re-homes a leading glue onto it. */
|
|
104
|
+
abstract withLeadingTrivia(trivia: GlueAstNode | undefined): BlockAstNode;
|
|
105
|
+
/** Prepends {@link leadingTrivia}, if any, ahead of the block's own children. */
|
|
106
|
+
protected _withLeading(own: readonly AstNode[]): readonly AstNode[];
|
|
107
|
+
}
|
|
58
108
|
|
|
59
109
|
/**
|
|
60
110
|
* One block's place in the rendered document.
|
|
@@ -79,13 +129,15 @@ export declare interface BlockMeasurement {
|
|
|
79
129
|
readonly viewNode: ViewNode | undefined;
|
|
80
130
|
}
|
|
81
131
|
|
|
82
|
-
export declare class BlockQuoteAstNode extends
|
|
132
|
+
export declare class BlockQuoteAstNode extends BlockAstNodeBase {
|
|
83
133
|
readonly content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[];
|
|
134
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
84
135
|
readonly kind = "blockQuote";
|
|
85
|
-
constructor(content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[]);
|
|
136
|
+
constructor(content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
86
137
|
get children(): readonly AstNode[];
|
|
87
138
|
get blocks(): readonly BlockAstNode[];
|
|
88
139
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
140
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): BlockQuoteAstNode;
|
|
89
141
|
}
|
|
90
142
|
|
|
91
143
|
declare class BlockQuoteViewData {
|
|
@@ -95,7 +147,7 @@ declare class BlockQuoteViewData {
|
|
|
95
147
|
constructor(ast: BlockQuoteAstNode, content: readonly AnyViewData[]);
|
|
96
148
|
}
|
|
97
149
|
|
|
98
|
-
declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData;
|
|
150
|
+
declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData | UnhandledBlockViewData;
|
|
99
151
|
|
|
100
152
|
/**
|
|
101
153
|
* Base view node for everything the editor renders, generic over the
|
|
@@ -116,6 +168,17 @@ export declare class BlockViewNode<T extends AnyViewData = AnyViewData> extends
|
|
|
116
168
|
constructor(data: T, dom: globalThis.Node, children: readonly ViewNode[]);
|
|
117
169
|
get block(): BlockAstNode;
|
|
118
170
|
get element(): HTMLElement;
|
|
171
|
+
/**
|
|
172
|
+
* The horizontal scroll viewport for selection/caret clipping
|
|
173
|
+
* ({@link blockViewportClip}). For most blocks the scroller *is*
|
|
174
|
+
* {@link element} — a code / math / unhandled block's `element` is the very
|
|
175
|
+
* `overflow-x: auto` box that scrolls. A table is the exception: its
|
|
176
|
+
* `element` stays the inner `<table>` (so the active/markers classes and
|
|
177
|
+
* `.md-table` theme styling are unaffected), but the box that actually
|
|
178
|
+
* scrolls is the wrapping `.md-table-wrapper`, so {@link TableViewNode}
|
|
179
|
+
* overrides this to return that wrapper.
|
|
180
|
+
*/
|
|
181
|
+
get scrollElement(): HTMLElement;
|
|
119
182
|
/**
|
|
120
183
|
* Whether this already-built node can stand in for `data` unchanged. The
|
|
121
184
|
* builder preserves view-data identity for any subtree whose ast and
|
|
@@ -139,9 +202,10 @@ export declare interface BlockViewOptions {
|
|
|
139
202
|
/**
|
|
140
203
|
* Opens a link's URL. Called when the user activates a link: a plain click
|
|
141
204
|
* while the link's block is inactive (rendered), or a Ctrl/Cmd+click while it
|
|
142
|
-
* is active (source shown).
|
|
205
|
+
* is active (source shown). Return `false` to use the anchor's native
|
|
206
|
+
* navigation behavior.
|
|
143
207
|
*/
|
|
144
|
-
readonly onOpenLink?: (url: string, event: MouseEvent) => void;
|
|
208
|
+
readonly onOpenLink?: (url: string, event: MouseEvent) => false | void;
|
|
145
209
|
/**
|
|
146
210
|
* Colours fenced code blocks. When set, a code block's content is rendered
|
|
147
211
|
* as a sequence of token spans instead of one plain text node. This is the
|
|
@@ -161,15 +225,32 @@ export declare interface BlockViewOptions {
|
|
|
161
225
|
* `katexEditableIdentifiers.ts`).
|
|
162
226
|
*/
|
|
163
227
|
readonly renderMath?: (request: MathRenderRequest) => MathRendering | undefined;
|
|
228
|
+
/**
|
|
229
|
+
* Pluggable factory for an in-place, interactive editor that replaces the
|
|
230
|
+
* *rendered* (inactive) form of a fenced code block — see
|
|
231
|
+
* {@link IEmbeddedCodeEditor}. When it returns an editor for the block's
|
|
232
|
+
* language, that editor's element is mounted instead of the highlighted
|
|
233
|
+
* code, and content flows both ways as string edits. Returning `undefined`
|
|
234
|
+
* falls back to the default rendering. EXPERIMENTAL.
|
|
235
|
+
*/
|
|
236
|
+
readonly embeddedCodeEditorFactory?: IEmbeddedCodeEditorFactory;
|
|
237
|
+
/**
|
|
238
|
+
* Called when an {@link IEmbeddedCodeEditor} edits its content. `contentEdit`
|
|
239
|
+
* is in the block's *content* coordinates; the host translates it to a
|
|
240
|
+
* document edit (via {@link CodeBlockAstNode.codeOffset} and the block's
|
|
241
|
+
* offset) and applies it to the model.
|
|
242
|
+
*/
|
|
243
|
+
readonly onEmbeddedCodeEditorEdit?: (block: CodeBlockAstNode, contentEdit: StringEdit) => void;
|
|
164
244
|
}
|
|
165
245
|
|
|
166
|
-
export declare class CodeBlockAstNode extends
|
|
246
|
+
export declare class CodeBlockAstNode extends BlockAstNodeBase {
|
|
167
247
|
readonly language: string;
|
|
168
248
|
readonly content: readonly (MarkerAstNode | GlueAstNode)[];
|
|
249
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
169
250
|
readonly kind = "codeBlock";
|
|
170
251
|
private _previous?;
|
|
171
252
|
private _contentEdit?;
|
|
172
|
-
constructor(language: string, content: readonly (MarkerAstNode | GlueAstNode)[]);
|
|
253
|
+
constructor(language: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
173
254
|
get children(): readonly AstNode[];
|
|
174
255
|
get openFence(): MarkerAstNode | undefined;
|
|
175
256
|
get closeFence(): MarkerAstNode | undefined;
|
|
@@ -177,6 +258,7 @@ export declare class CodeBlockAstNode extends AstNode {
|
|
|
177
258
|
/** Relative start offset of the {@link code} marker within this block. */
|
|
178
259
|
get codeOffset(): number;
|
|
179
260
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
261
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): CodeBlockAstNode;
|
|
180
262
|
protected _localEquals(o: this): boolean;
|
|
181
263
|
/**
|
|
182
264
|
* A copy of this block carrying an incremental link to `previous`:
|
|
@@ -234,10 +316,241 @@ export declare class CodeBlockViewNode extends BlockViewNode<CodeBlockViewData>
|
|
|
234
316
|
* its predecessor's subscription explicitly.
|
|
235
317
|
*/
|
|
236
318
|
private _snapshotSub;
|
|
319
|
+
/**
|
|
320
|
+
* An in-place interactive editor (e.g. an iframe) mounted instead of the
|
|
321
|
+
* rendered code. Like {@link _session} it is adopted from `previous` across
|
|
322
|
+
* rebuilds so the underlying editor keeps its state, and must be disposed
|
|
323
|
+
* manually (a node reused as `previous` is never {@link dispose}d).
|
|
324
|
+
*/
|
|
325
|
+
private _embeddedEditor;
|
|
237
326
|
constructor(data: CodeBlockViewData, options: BlockViewOptions | undefined, previous: ViewNode | undefined);
|
|
238
327
|
dispose(): void;
|
|
239
328
|
}
|
|
240
329
|
|
|
330
|
+
/** A persistent comment anchored to a source range. */
|
|
331
|
+
declare interface Comment_2 {
|
|
332
|
+
readonly id: string;
|
|
333
|
+
/** Source range the comment refers to (its highlighted region). */
|
|
334
|
+
readonly range: OffsetRange;
|
|
335
|
+
/** The comment text. */
|
|
336
|
+
readonly body: string;
|
|
337
|
+
/** Display name of the author, if any. */
|
|
338
|
+
readonly author?: string;
|
|
339
|
+
/** Creation time (epoch ms), used to render a relative timestamp. */
|
|
340
|
+
readonly createdAt?: number;
|
|
341
|
+
}
|
|
342
|
+
export { Comment_2 as Comment }
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* A self-contained comment input box — a rounded panel with an auto-growing
|
|
346
|
+
* textarea and a send button, styled after the gdocs/Word "add a comment"
|
|
347
|
+
* affordance.
|
|
348
|
+
*
|
|
349
|
+
* This widget is *positioning-agnostic*: it only owns its own DOM and state.
|
|
350
|
+
* A host (the comment-mode controller, or a fixture) mounts {@link element}
|
|
351
|
+
* wherever it likes and is responsible for placing it relative to a selection.
|
|
352
|
+
*
|
|
353
|
+
* State is observable-driven (no framework): {@link value} reflects the live
|
|
354
|
+
* textarea content; submit/cancel are reported through the option callbacks.
|
|
355
|
+
*/
|
|
356
|
+
export declare class CommentInputWidget extends Disposable {
|
|
357
|
+
private readonly _options?;
|
|
358
|
+
readonly element: HTMLElement;
|
|
359
|
+
private readonly _textarea;
|
|
360
|
+
private readonly _measure;
|
|
361
|
+
private readonly _submitButton;
|
|
362
|
+
private readonly _value;
|
|
363
|
+
/** Live, untrimmed textarea content. */
|
|
364
|
+
get value(): IObservable<string>;
|
|
365
|
+
/** The raw textarea, exposed so a host can move focus into it (e.g. on Tab). */
|
|
366
|
+
get inputElement(): HTMLTextAreaElement;
|
|
367
|
+
constructor(_options?: CommentInputWidgetOptions | undefined);
|
|
368
|
+
/** Move focus into the textarea (caret at the end). */
|
|
369
|
+
focus(): void;
|
|
370
|
+
/** Replace the textarea content. */
|
|
371
|
+
setText(text: string): void;
|
|
372
|
+
/** Clear the textarea. */
|
|
373
|
+
clear(): void;
|
|
374
|
+
private _submit;
|
|
375
|
+
private _autoSize;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export declare interface CommentInputWidgetOptions {
|
|
379
|
+
/** Placeholder shown while the textarea is empty. Defaults to "Add Comment". */
|
|
380
|
+
readonly placeholder?: string;
|
|
381
|
+
/** Called after the textarea changes size. */
|
|
382
|
+
readonly onDidChangeSize?: () => void;
|
|
383
|
+
/**
|
|
384
|
+
* Called when the user submits a non-empty comment (Enter or the send
|
|
385
|
+
* button). The text is trimmed; never called with an empty string.
|
|
386
|
+
*/
|
|
387
|
+
readonly onSubmit?: (text: string) => void;
|
|
388
|
+
/** Called when the user dismisses the input (Escape). */
|
|
389
|
+
readonly onCancel?: () => void;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Comment mode — a gdocs/Word-style "add a comment" affordance layered on top of
|
|
394
|
+
* the editor *without modifying it*. It reads the editor's public observables
|
|
395
|
+
* ({@link EditorModel.readonlyMode}, {@link EditorModel.selection}) and the
|
|
396
|
+
* exposed {@link EditorView.caretRect} geometry, and mounts a
|
|
397
|
+
* {@link CommentInputWidget} into {@link EditorView.overlayContainer}.
|
|
398
|
+
*
|
|
399
|
+
* Behaviour:
|
|
400
|
+
* - Only active in read-only mode (the "review" view).
|
|
401
|
+
* - When the selection is non-empty, the input box appears next to the caret
|
|
402
|
+
* (the selection's active end) but does NOT take focus, so keyboard selection
|
|
403
|
+
* keeps working. Press Tab to move focus into the box, then type.
|
|
404
|
+
* - The box appears on mouse-up, not mid-drag, so it doesn't flicker/jump
|
|
405
|
+
* while a selection is being dragged out (keyboard selection shows at once).
|
|
406
|
+
* - While the box has focus or holds a draft it is frozen in place (selection
|
|
407
|
+
* changes, drags and clicks no longer move it). It is dismissed by Escape,
|
|
408
|
+
* by submitting, or by blurring an empty box.
|
|
409
|
+
* - The editor's logical caret geometry remains available for anchoring in
|
|
410
|
+
* read-only mode even though the painted caret is hidden. While the box has
|
|
411
|
+
* focus, `.md-comment-active` also suppresses the painted caret in any mode.
|
|
412
|
+
*/
|
|
413
|
+
export declare class CommentModeController extends Disposable {
|
|
414
|
+
private readonly _model;
|
|
415
|
+
private readonly _view;
|
|
416
|
+
private readonly _options?;
|
|
417
|
+
private readonly _widget;
|
|
418
|
+
private readonly _gap;
|
|
419
|
+
private _visible;
|
|
420
|
+
private _anchorX;
|
|
421
|
+
private _pinnedRange;
|
|
422
|
+
/**
|
|
423
|
+
* The range a comment was just submitted for. The box stays hidden for it
|
|
424
|
+
* until the selection changes, so submitting doesn't immediately re-summon an
|
|
425
|
+
* empty box on the still-selected text.
|
|
426
|
+
*/
|
|
427
|
+
private _submittedRange;
|
|
428
|
+
constructor(_model: EditorModel, _view: EditorView, _options?: CommentModeControllerOptions | undefined);
|
|
429
|
+
private _update;
|
|
430
|
+
private _show;
|
|
431
|
+
private _layoutHorizontally;
|
|
432
|
+
/** Force-hide and clear the box (used by Escape and submit). */
|
|
433
|
+
private _hide;
|
|
434
|
+
/**
|
|
435
|
+
* Hide unless the user is engaged with the box: it has focus or holds a
|
|
436
|
+
* non-empty draft. This preserves in-progress text and keeps a focused box
|
|
437
|
+
* open (it is dismissed explicitly via Escape/submit, or by blurring it).
|
|
438
|
+
*/
|
|
439
|
+
private _autoHide;
|
|
440
|
+
private _widgetHasFocus;
|
|
441
|
+
/**
|
|
442
|
+
* The visible viewport (client coords) used for the flip-above decision: the
|
|
443
|
+
* nearest scrollable ancestor of the editor. `.md-editor` itself spans the
|
|
444
|
+
* full document height and never clips, so measuring against it would always
|
|
445
|
+
* report room below. Falls back to the window when nothing scrolls.
|
|
446
|
+
*/
|
|
447
|
+
private _getViewportRect;
|
|
448
|
+
private _hideAndRefocus;
|
|
449
|
+
private _submit;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export declare interface CommentModeControllerOptions {
|
|
453
|
+
/** Called when the user submits a comment for the current selection. */
|
|
454
|
+
readonly onSubmit?: (submission: CommentSubmission) => void;
|
|
455
|
+
/** Gap (px) between the bottom of the selection and the top of the input box. */
|
|
456
|
+
readonly gap?: number;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/** Human-readable labels (for pickers / dropdowns). */
|
|
460
|
+
export declare const COMMENTS_DESIGN_LABELS: Record<CommentsDesign, string>;
|
|
461
|
+
|
|
462
|
+
/** design id → presenter factory over a shared CommentsModel + EditorView. */
|
|
463
|
+
export declare const COMMENTS_DESIGNS: Record<CommentsDesign, CommentsPresenterFactory>;
|
|
464
|
+
|
|
465
|
+
/** The available comment rendering designs. */
|
|
466
|
+
export declare type CommentsDesign = 'connected' | 'vscode' | 'vscode-v2';
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Seedable store of {@link Comment}s for the comment-mode contribution. Owns the
|
|
470
|
+
* comment list and the shared hover state; it has no opinion on rendering or
|
|
471
|
+
* persistence — a host seeds it via {@link set}/{@link add} and observes
|
|
472
|
+
* {@link comments}.
|
|
473
|
+
*/
|
|
474
|
+
export declare class CommentsModel {
|
|
475
|
+
private readonly _comments;
|
|
476
|
+
/** Monotonic counter for ids of comments created via {@link create}. */
|
|
477
|
+
private _sequence;
|
|
478
|
+
/** The current comments, in insertion order. */
|
|
479
|
+
get comments(): IObservable<readonly Comment_2[]>;
|
|
480
|
+
/**
|
|
481
|
+
* The comment currently hovered (by its card or its highlight), or
|
|
482
|
+
* `undefined`. Shared so the card and the highlight can react together.
|
|
483
|
+
*/
|
|
484
|
+
readonly hoveredId: ISettableObservable<string | undefined>;
|
|
485
|
+
/** Replace the whole comment set. */
|
|
486
|
+
set(comments: readonly Comment_2[]): void;
|
|
487
|
+
/**
|
|
488
|
+
* Create a comment from a user submission and append it, generating its `id`
|
|
489
|
+
* and `createdAt` here so id/time allocation stays the store's concern (the
|
|
490
|
+
* UI only supplies the range and text). Returns the created comment.
|
|
491
|
+
*/
|
|
492
|
+
create(input: {
|
|
493
|
+
range: OffsetRange;
|
|
494
|
+
body: string;
|
|
495
|
+
author?: string;
|
|
496
|
+
}): Comment_2;
|
|
497
|
+
/** Append a comment. */
|
|
498
|
+
add(comment: Comment_2): void;
|
|
499
|
+
/** Remove a comment by id. */
|
|
500
|
+
remove(id: string): void;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/** Optional, design-specific context a presenter may use (ignored by others). */
|
|
504
|
+
export declare interface CommentsPresenterContext {
|
|
505
|
+
/** Light/dark hint for the token-wrapped VS Code widget designs. */
|
|
506
|
+
readonly theme?: 'light' | 'dark';
|
|
507
|
+
/**
|
|
508
|
+
* Resolves a source offset to a 1-based line number, for designs that show
|
|
509
|
+
* line info (the VS Code V1 card). Optional because the model itself carries
|
|
510
|
+
* no text; the host (which owns the source) supplies it.
|
|
511
|
+
*/
|
|
512
|
+
readonly resolveLine?: (offset: number) => number;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** Builds a presenter for a given model + editor view. */
|
|
516
|
+
export declare type CommentsPresenterFactory = (model: CommentsModel, view: EditorView, context?: CommentsPresenterContext) => ICommentsPresenter;
|
|
517
|
+
|
|
518
|
+
/** A comment the user submitted, with the source range it was anchored to. */
|
|
519
|
+
export declare interface CommentSubmission {
|
|
520
|
+
readonly text: string;
|
|
521
|
+
readonly range: OffsetRange;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Renders persistent comments as a gdocs-style side rail: each comment's range
|
|
526
|
+
* is highlighted (reusing the editor's selection geometry via
|
|
527
|
+
* {@link EditorView.rangeRects}), a leader line curves from the bottom of that
|
|
528
|
+
* highlight to a card stacked in the right rail, and cards never overlap.
|
|
529
|
+
*
|
|
530
|
+
* Everything is mounted into {@link EditorView.overlayContainer} so it shares
|
|
531
|
+
* the selection/caret coordinate space and scrolls with the document. When the
|
|
532
|
+
* editor's natural right margin is too narrow for the rail, the view reserves
|
|
533
|
+
* proportional space by padding the editor on the right — but only while there
|
|
534
|
+
* are comments.
|
|
535
|
+
*/
|
|
536
|
+
export declare class CommentsView extends Disposable {
|
|
537
|
+
private readonly _model;
|
|
538
|
+
private readonly _view;
|
|
539
|
+
private readonly _layer;
|
|
540
|
+
private readonly _entries;
|
|
541
|
+
constructor(_model: CommentsModel, _view: EditorView);
|
|
542
|
+
private _createLayer;
|
|
543
|
+
private _update;
|
|
544
|
+
/** Create/update/remove per-comment DOM to match `comments`. */
|
|
545
|
+
private _reconcile;
|
|
546
|
+
private _createEntry;
|
|
547
|
+
private _fillCard;
|
|
548
|
+
private _disposeEntry;
|
|
549
|
+
/** Position highlights, cards (stacked) and leader lines. */
|
|
550
|
+
private _layout;
|
|
551
|
+
private _applyHover;
|
|
552
|
+
}
|
|
553
|
+
|
|
241
554
|
/**
|
|
242
555
|
* A {@link MonacoSyntaxHighlighter} preloaded with a handful of common Monarch
|
|
243
556
|
* grammars (plus the usual short aliases). Unknown languages fall back to an
|
|
@@ -301,6 +614,19 @@ export declare class CursorView extends Disposable {
|
|
|
301
614
|
export declare interface CursorViewOptions {
|
|
302
615
|
readonly offset: IObservable<SourceOffset | undefined>;
|
|
303
616
|
readonly visualLineMap: IObservable<VisualLineMap>;
|
|
617
|
+
/**
|
|
618
|
+
* The mounted blocks, used to hide the caret when it sits at an offset that
|
|
619
|
+
* has been scrolled out of its (horizontally scrolling) block's viewport —
|
|
620
|
+
* matching how the selection is clipped there.
|
|
621
|
+
*/
|
|
622
|
+
readonly blocks?: IObservable<readonly SelectionBlock[]>;
|
|
623
|
+
/**
|
|
624
|
+
* When set, the caret is drawn over the transient empty paragraph instead
|
|
625
|
+
* of at {@link offset} — its rect (in client coordinates) comes straight
|
|
626
|
+
* from that synthetic element's geometry, since it has no visual-line-map
|
|
627
|
+
* entry. Takes priority over the normal offset-based placement.
|
|
628
|
+
*/
|
|
629
|
+
readonly pendingCaretRect?: IObservable<Rect2D | undefined>;
|
|
304
630
|
}
|
|
305
631
|
|
|
306
632
|
export declare class CursorViewRendering {
|
|
@@ -322,6 +648,74 @@ export declare const deleteWordLeft: EditCommand;
|
|
|
322
648
|
|
|
323
649
|
export declare const deleteWordRight: EditCommand;
|
|
324
650
|
|
|
651
|
+
/**
|
|
652
|
+
* A read-only "removed" decoration: an original block rendered (red) above its
|
|
653
|
+
* place in the modified document, occupying vertical space like a view-zone but
|
|
654
|
+
* contributing **zero** source length, so the editor's source mapping stays the
|
|
655
|
+
* modified document and editing is unaffected. Used for `removed` and the
|
|
656
|
+
* original side of a `replaced` block in editor diff mode.
|
|
657
|
+
*/
|
|
658
|
+
declare class DiffDecorationViewData {
|
|
659
|
+
readonly ast: AstNode;
|
|
660
|
+
readonly side: BlockViewData;
|
|
661
|
+
readonly deletedRanges: readonly DiffHighlightRange[];
|
|
662
|
+
/** True when the whole block was removed: solid red band, no word rects. */
|
|
663
|
+
readonly whole: boolean;
|
|
664
|
+
/** Absolute offset of this block in the *original* document. */
|
|
665
|
+
readonly originalStart: number;
|
|
666
|
+
readonly kind = "diffDecoration";
|
|
667
|
+
constructor(ast: AstNode, side: BlockViewData, deletedRanges: readonly DiffHighlightRange[],
|
|
668
|
+
/** True when the whole block was removed: solid red band, no word rects. */
|
|
669
|
+
whole: boolean,
|
|
670
|
+
/** Absolute offset of this block in the *original* document. */
|
|
671
|
+
originalStart: number);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/** A word/character highlight inside one diff side, in block-local coords. */
|
|
675
|
+
declare interface DiffHighlightRange {
|
|
676
|
+
readonly range: OffsetRange;
|
|
677
|
+
readonly kind: 'inserted' | 'deleted';
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* A changed block rendered as its original form stacked over its modified form
|
|
682
|
+
* (either side may be absent for a pure deletion/insertion). It is itself a
|
|
683
|
+
* document child the renderer mounts like a block; its {@link ast} is the
|
|
684
|
+
* surviving side's ast, used only for view-node identity/reuse.
|
|
685
|
+
*/
|
|
686
|
+
declare class DiffHunkViewData {
|
|
687
|
+
readonly ast: AstNode;
|
|
688
|
+
readonly original: DiffSideViewData | undefined;
|
|
689
|
+
readonly modified: DiffSideViewData | undefined;
|
|
690
|
+
readonly kind = "diffHunk";
|
|
691
|
+
constructor(ast: AstNode, original: DiffSideViewData | undefined, modified: DiffSideViewData | undefined);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* The recursive classification of a diff. Each item describes one aligned
|
|
696
|
+
* position in the merged document:
|
|
697
|
+
*
|
|
698
|
+
* - `unchanged` — render the (modified) node once, neutral.
|
|
699
|
+
* - `added` — exists only in the modified document (green).
|
|
700
|
+
* - `removed` — exists only in the original document (red).
|
|
701
|
+
* - `replaced` — a *leaf* block changed in place → render original over
|
|
702
|
+
* modified, with word-level {@link AnnotatedRange}s on each.
|
|
703
|
+
* - `nested` — a *container* changed → render it once and diff its
|
|
704
|
+
* {@link NestedItem.children} recursively.
|
|
705
|
+
*
|
|
706
|
+
* Offsets ({@link UnchangedItem.modifiedStart} etc.) are absolute in their
|
|
707
|
+
* respective documents, so a renderer/visualizer can slice the source text.
|
|
708
|
+
*/
|
|
709
|
+
declare type DiffItem = UnchangedItem | AddedItem | RemovedItem | ReplacedItem | NestedItem;
|
|
710
|
+
|
|
711
|
+
/** One side (original or modified) of a {@link DiffHunkViewData}. */
|
|
712
|
+
declare interface DiffSideViewData {
|
|
713
|
+
readonly view: BlockViewData;
|
|
714
|
+
/** Render in active form (markers/whitespace visible). */
|
|
715
|
+
readonly active: boolean;
|
|
716
|
+
readonly ranges: readonly DiffHighlightRange[];
|
|
717
|
+
}
|
|
718
|
+
|
|
325
719
|
export declare class DocumentAstNode extends AstNode {
|
|
326
720
|
readonly content: readonly (BlockAstNode | GlueAstNode)[];
|
|
327
721
|
readonly kind = "document";
|
|
@@ -346,13 +740,21 @@ declare interface DocumentBlockViewData {
|
|
|
346
740
|
readonly view: BlockViewData;
|
|
347
741
|
}
|
|
348
742
|
|
|
349
|
-
/** A mounted document child: a block
|
|
743
|
+
/** A mounted document child: a block, a run of inter-block glue, the
|
|
744
|
+
* transient empty paragraph (see {@link PendingParagraphViewData}), or a
|
|
745
|
+
* {@link DiffHunkViewData diff hunk} (stacked original/modified blocks). */
|
|
350
746
|
declare interface DocumentChildViewData {
|
|
351
747
|
readonly absoluteStart: number;
|
|
352
|
-
/** For a block: selection reaches it. For glue:
|
|
748
|
+
/** For a block: selection reaches it. For glue: always false (unowned, hidden). */
|
|
353
749
|
readonly isActive: boolean;
|
|
354
|
-
readonly view: BlockViewData | GlueViewData;
|
|
355
|
-
readonly kind: 'block' | 'glue';
|
|
750
|
+
readonly view: BlockViewData | GlueViewData | PendingParagraphViewData | DiffHunkViewData | DiffDecorationViewData;
|
|
751
|
+
readonly kind: 'block' | 'glue' | 'pendingParagraph' | 'diffHunk' | 'diffDecoration';
|
|
752
|
+
/**
|
|
753
|
+
* Diff mode: how this (modified) block changed. `added` = a whole new block
|
|
754
|
+
* (strong green band, no inline rects); `modified` = a partial change (light
|
|
755
|
+
* band + inline rects on the changed words).
|
|
756
|
+
*/
|
|
757
|
+
readonly diffKind?: 'added' | 'modified';
|
|
356
758
|
}
|
|
357
759
|
|
|
358
760
|
/**
|
|
@@ -408,6 +810,8 @@ declare class DocumentViewData {
|
|
|
408
810
|
*/
|
|
409
811
|
export declare class DocumentViewNode extends ViewNode {
|
|
410
812
|
readonly blocks: readonly DocumentBlock[];
|
|
813
|
+
/** The transient empty-paragraph element, when one is armed. */
|
|
814
|
+
readonly pendingElement?: HTMLElement | undefined;
|
|
411
815
|
static create(viewData: DocumentViewData, options: BlockViewOptions | undefined, previous: DocumentViewNode | undefined): DocumentViewNode;
|
|
412
816
|
private constructor();
|
|
413
817
|
/** The stable content element this document mounts its children into. */
|
|
@@ -437,14 +841,21 @@ export declare type EditCommand = (ctx: CursorCommandContext) => {
|
|
|
437
841
|
*
|
|
438
842
|
* Owns the only non-derivable controller state:
|
|
439
843
|
* - `_desiredColumn` — sticky column for up/down navigation
|
|
844
|
+
* - `_clickCount` / `_lastPointerDown` — multi-click detection for pointer
|
|
845
|
+
* input, since `pointerdown` events (unlike `mousedown`) don't populate
|
|
846
|
+
* `detail` with a click count.
|
|
440
847
|
*/
|
|
441
848
|
export declare class EditorController extends Disposable {
|
|
442
849
|
private readonly _model;
|
|
443
850
|
private readonly _view;
|
|
444
851
|
private _desiredColumn;
|
|
445
|
-
|
|
852
|
+
/** Running click count for the current multi-click sequence (1, 2, 3, …). */
|
|
853
|
+
private _clickCount;
|
|
854
|
+
/** Timestamp and position of the previous pointer-down, for multi-click detection. */
|
|
855
|
+
private _lastPointerDown;
|
|
856
|
+
constructor(_model: EditorModel, _view: EditorView, options?: EditorControllerOptions);
|
|
446
857
|
private readonly _handleTextUpdate;
|
|
447
|
-
private readonly
|
|
858
|
+
private readonly _handlePointerDown;
|
|
448
859
|
private _makeCursorContext;
|
|
449
860
|
private _makeVisualCursorContext;
|
|
450
861
|
private _executeCursorCommand;
|
|
@@ -454,11 +865,25 @@ export declare class EditorController extends Disposable {
|
|
|
454
865
|
cursorDown(extend?: boolean): void;
|
|
455
866
|
/** Move the cursor up one visual line (Arrow Up). */
|
|
456
867
|
cursorUp(extend?: boolean): void;
|
|
457
|
-
private readonly _handleCopy;
|
|
458
|
-
private readonly _handleCut;
|
|
459
|
-
private readonly _handlePaste;
|
|
460
868
|
private _selectedText;
|
|
869
|
+
private readonly _updateModifierState;
|
|
870
|
+
private readonly _clearModifierState;
|
|
461
871
|
private readonly _handleKeyDown;
|
|
872
|
+
/**
|
|
873
|
+
* Context-aware Enter: splits / line-breaks via {@link insertSmartEnter}, or
|
|
874
|
+
* arms a transient empty paragraph when at the end of a paragraph.
|
|
875
|
+
*/
|
|
876
|
+
private _smartEnter;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/** Options for an {@link EditorController}. */
|
|
880
|
+
export declare interface EditorControllerOptions {
|
|
881
|
+
/**
|
|
882
|
+
* How copy/cut/paste is handled. Defaults to {@link NativeClipboardStrategy},
|
|
883
|
+
* which reads the browser's native clipboard events — pass a different
|
|
884
|
+
* strategy (e.g. `AsyncClipboardStrategy`) in hosts that swallow them.
|
|
885
|
+
*/
|
|
886
|
+
readonly clipboardStrategy?: IClipboardStrategy;
|
|
462
887
|
}
|
|
463
888
|
|
|
464
889
|
export declare class EditorModel {
|
|
@@ -471,11 +896,43 @@ export declare class EditorModel {
|
|
|
471
896
|
*/
|
|
472
897
|
private _pendingEdit;
|
|
473
898
|
readonly sourceText: ISettableObservable<StringValue, void>;
|
|
899
|
+
/**
|
|
900
|
+
* Read-only mode. When `true`, the editor never reveals a block's source
|
|
901
|
+
* markers (markdown special characters like `**`, `#`, list bullets, code
|
|
902
|
+
* fences, `$…$`) — every block stays in its clean rendered form regardless
|
|
903
|
+
* of where the caret/selection is — and source-mutating edits are ignored.
|
|
904
|
+
* Plain text selection still works everywhere (so the user can copy). The
|
|
905
|
+
* default (`false`) is the normal editing mode where the active block
|
|
906
|
+
* reveals its markers.
|
|
907
|
+
*/
|
|
908
|
+
readonly readonlyMode: ISettableObservable<boolean, void>;
|
|
474
909
|
/**
|
|
475
910
|
* The current selection, or `undefined` when the editor has no caret
|
|
476
911
|
* (e.g. an inactive/unfocused rendering).
|
|
477
912
|
*/
|
|
478
913
|
readonly selection: ISettableObservable<Selection_2 | undefined, void>;
|
|
914
|
+
/**
|
|
915
|
+
* Whether a Ctrl/Cmd modifier is currently held. Set by the controller from
|
|
916
|
+
* live keyboard state; the view reads it to show the link-open affordance
|
|
917
|
+
* (underline + pointer cursor) only while a Ctrl/Cmd+click would open a link
|
|
918
|
+
* whose block is active.
|
|
919
|
+
*/
|
|
920
|
+
readonly ctrlOrMetaDown: ISettableObservable<boolean, void>;
|
|
921
|
+
/**
|
|
922
|
+
* Whether a pointer-driven selection drag is currently in progress. Set by
|
|
923
|
+
* the controller between the pointer-down that starts the drag and the
|
|
924
|
+
* pointer-up/cancel that ends it. Contributions read it to defer UI that
|
|
925
|
+
* would otherwise flicker mid-drag (e.g. the comment input box appears only
|
|
926
|
+
* once the drag ends).
|
|
927
|
+
*/
|
|
928
|
+
readonly isSelecting: ISettableObservable<boolean, void>;
|
|
929
|
+
/**
|
|
930
|
+
* Gutter markers (source-control style change indicators) painted in the
|
|
931
|
+
* left gutter. Each entry maps a source {@link OffsetRange} to a change kind
|
|
932
|
+
* — see {@link GutterMarker}. Purely decorative: markers never affect the
|
|
933
|
+
* parsed {@link document}, selection, or layout. Empty by default.
|
|
934
|
+
*/
|
|
935
|
+
readonly gutterMarkers: ISettableObservable<readonly GutterMarker[], void>;
|
|
479
936
|
/**
|
|
480
937
|
* Forces the rendered active-block set. `undefined` (the default)
|
|
481
938
|
* derives the set from the current selection range (see
|
|
@@ -484,6 +941,13 @@ export declare class EditorModel {
|
|
|
484
941
|
* collapsed/inactive rendering.
|
|
485
942
|
*/
|
|
486
943
|
readonly activeBlocksOverride: ISettableObservable<readonly BlockAstNode[] | typeof NO_ACTIVE_BLOCKS | undefined, void>;
|
|
944
|
+
/**
|
|
945
|
+
* The transient empty-paragraph editing state, or `undefined` when none is
|
|
946
|
+
* armed. See {@link PendingParagraph}. This is *not* document data — it is
|
|
947
|
+
* cleared by any source edit and lives only between the Enter that armed it
|
|
948
|
+
* and the next keystroke.
|
|
949
|
+
*/
|
|
950
|
+
readonly pendingParagraph: ISettableObservable<PendingParagraph | undefined, void>;
|
|
487
951
|
readonly cursorOffset: IObservableWithChange<number | undefined, void>;
|
|
488
952
|
/**
|
|
489
953
|
* The parsed document. Threads the previous document into the parser so
|
|
@@ -507,6 +971,43 @@ export declare class EditorModel {
|
|
|
507
971
|
* collapsed this is a one-element set holding {@link activeBlock}.
|
|
508
972
|
*/
|
|
509
973
|
readonly activeBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
|
|
974
|
+
/**
|
|
975
|
+
* The baseline document to diff against. When set, the editor renders in
|
|
976
|
+
* diff mode: the modified document ({@link document}) stays editable, while
|
|
977
|
+
* the baseline's removed/changed blocks are shown as read-only decorations.
|
|
978
|
+
* `undefined` (the default) renders normally.
|
|
979
|
+
*/
|
|
980
|
+
readonly baseline: ISettableObservable<StringValue | undefined, void>;
|
|
981
|
+
private readonly _baselineDocument;
|
|
982
|
+
/**
|
|
983
|
+
* The diff of {@link baseline} → {@link document}, or `undefined` when no
|
|
984
|
+
* baseline is set. The view renders the {@link DiffItem}s as stacked
|
|
985
|
+
* decorations; `insertedRanges` (modified-side change spans) drive the green
|
|
986
|
+
* word-level highlight.
|
|
987
|
+
*/
|
|
988
|
+
readonly diff: IObservableWithChange< {
|
|
989
|
+
items: DiffItem[];
|
|
990
|
+
insertedRanges: OffsetRange[];
|
|
991
|
+
changedBlocks: Set<BlockAstNode>;
|
|
992
|
+
} | undefined, void>;
|
|
993
|
+
/**
|
|
994
|
+
* Arm a {@link PendingParagraph} at the given gap, minting a fresh synthetic
|
|
995
|
+
* AST node for it, and park the caret at the gap start. No source edit is
|
|
996
|
+
* applied — the blank line exists only in the view until it is materialized.
|
|
997
|
+
*/
|
|
998
|
+
armPendingParagraph(req: {
|
|
999
|
+
anchorBlock: BlockAstNode;
|
|
1000
|
+
replaceRange: OffsetRange;
|
|
1001
|
+
atEof: boolean;
|
|
1002
|
+
}): void;
|
|
1003
|
+
/** Discard the pending paragraph (if any) without touching the source. */
|
|
1004
|
+
cancelPendingParagraph(): void;
|
|
1005
|
+
/**
|
|
1006
|
+
* Turn the pending paragraph into real source: rewrite its gap so the typed
|
|
1007
|
+
* `text` becomes its own paragraph, separated from its neighbours by blank
|
|
1008
|
+
* lines, and place the caret after the inserted text.
|
|
1009
|
+
*/
|
|
1010
|
+
materializePendingParagraph(text: string): void;
|
|
510
1011
|
applyEdit(edit: StringEdit): void;
|
|
511
1012
|
applyEditForSelection(edit: StringEdit): void;
|
|
512
1013
|
}
|
|
@@ -540,8 +1041,18 @@ export declare class EditorView extends Disposable {
|
|
|
540
1041
|
readonly element: HTMLElement;
|
|
541
1042
|
readonly editContext: EditContext;
|
|
542
1043
|
readonly measuredLayout: MeasuredLayoutModel;
|
|
1044
|
+
/**
|
|
1045
|
+
* Inner container that holds the rendered document and the cursor/selection
|
|
1046
|
+
* overlays. The outer {@link element} spans the full width; this container
|
|
1047
|
+
* is what limited-width mode caps and centers, so the overlays (which anchor
|
|
1048
|
+
* to their parent's box) stay aligned with the content.
|
|
1049
|
+
*/
|
|
1050
|
+
private readonly _contentContainer;
|
|
543
1051
|
private readonly _cursorView;
|
|
544
1052
|
private readonly _selectionView;
|
|
1053
|
+
private readonly _gutterMarkersView;
|
|
1054
|
+
private readonly _diffHighlightsView;
|
|
1055
|
+
private _readonlyToggleButton;
|
|
545
1056
|
/**
|
|
546
1057
|
* The mounted block sequence, in source order. Rebuilt (not mutated) each
|
|
547
1058
|
* frame by {@link DocumentViewNode.create}; the view just swaps one
|
|
@@ -561,20 +1072,90 @@ export declare class EditorView extends Disposable {
|
|
|
561
1072
|
/** The current view-data tree (AST overlaid with selection flags), for debugging. */
|
|
562
1073
|
private readonly _viewData;
|
|
563
1074
|
get viewData(): IObservable<DocumentViewData | undefined>;
|
|
1075
|
+
/**
|
|
1076
|
+
* Caret rect (client coords) for the transient empty paragraph, or
|
|
1077
|
+
* `undefined` when none is armed. Set each frame from the synthetic
|
|
1078
|
+
* paragraph element's geometry and fed to the {@link CursorView}, which has
|
|
1079
|
+
* no visual-line-map entry to place the caret from otherwise.
|
|
1080
|
+
*/
|
|
1081
|
+
private readonly _pendingCaretRect;
|
|
564
1082
|
/**
|
|
565
1083
|
* The block cache projected for views (selection painting) that need to
|
|
566
1084
|
* react to mount/unmount. Derived from {@link _document}, so it stays in
|
|
567
1085
|
* lock-step without any manual bookkeeping.
|
|
568
1086
|
*/
|
|
569
1087
|
private readonly _selectionBlocksObs;
|
|
1088
|
+
/**
|
|
1089
|
+
* The caret rect (zero width) at the selection's active end, in
|
|
1090
|
+
* {@link overlayContainer}-local coordinates, or `undefined` when there is no
|
|
1091
|
+
* caret. This is the same geometry the editor paints its cursor from, so
|
|
1092
|
+
* contributions (e.g. comment mode) can anchor an overlay to the active end of
|
|
1093
|
+
* the selection — where the user's cursor is — without re-deriving geometry.
|
|
1094
|
+
*/
|
|
1095
|
+
private readonly _caretRect;
|
|
1096
|
+
get caretRect(): IObservable<Rect2D | undefined>;
|
|
1097
|
+
/**
|
|
1098
|
+
* The container that establishes the positioning context for the editor's
|
|
1099
|
+
* overlays (cursor, selection, gutter). Contributions mount their own
|
|
1100
|
+
* absolutely-positioned overlays here so they share the coordinate space of
|
|
1101
|
+
* {@link caretRect}.
|
|
1102
|
+
*/
|
|
1103
|
+
get overlayContainer(): HTMLElement;
|
|
1104
|
+
/**
|
|
1105
|
+
* Selection-style rectangles covering `range`, in {@link overlayContainer}-
|
|
1106
|
+
* local coordinates — the same geometry the live selection paints. Exposed so
|
|
1107
|
+
* contributions (e.g. persistent comments) can highlight arbitrary ranges and
|
|
1108
|
+
* anchor overlays to them. Recomputes when the measured layout changes.
|
|
1109
|
+
*/
|
|
1110
|
+
rangeRects(range: OffsetRange): IObservable<readonly SelectionRect[]>;
|
|
570
1111
|
constructor(_model: EditorModel, _options?: EditorViewOptions | undefined);
|
|
1112
|
+
/**
|
|
1113
|
+
* Mirrors the model's live Ctrl/Cmd state onto the editor root as
|
|
1114
|
+
* `.md-mod-down` so CSS can show the link-open underline and pointer cursor
|
|
1115
|
+
* only while a click would actually open the link: an inactive link opens on
|
|
1116
|
+
* a plain click, but an active link only opens with the modifier held.
|
|
1117
|
+
*/
|
|
1118
|
+
private _setupModifierTracking;
|
|
1119
|
+
/**
|
|
1120
|
+
* Renders the edit/read-only mode toggle. It flips the model's
|
|
1121
|
+
* {@link EditorModel.readonlyMode}: when locked (read-only) every block stays
|
|
1122
|
+
* in its clean rendered form (no markdown markers revealed) and edits are
|
|
1123
|
+
* ignored, while text selection still works. The control lives in a
|
|
1124
|
+
* zero-height *sticky* host inside the centered content container, so the
|
|
1125
|
+
* lock follows the content's right edge and remains pinned as the document
|
|
1126
|
+
* scrolls. The current mode is also mirrored onto the root as `.md-readonly`
|
|
1127
|
+
* for any CSS hooks.
|
|
1128
|
+
*/
|
|
1129
|
+
private _setupReadonlyToggle;
|
|
1130
|
+
/** Draws attention to the mode toggle after text input is attempted while locked. */
|
|
1131
|
+
showReadonlyEditingAttempt(): void;
|
|
571
1132
|
focus(): void;
|
|
1133
|
+
/**
|
|
1134
|
+
* Own point→offset resolution. When `true` (the default),
|
|
1135
|
+
* {@link resolveOffsetFromPoint} ignores the platform DOM hit-test
|
|
1136
|
+
* (`caretPositionFromPoint`) and snaps the point to the nearest offset purely
|
|
1137
|
+
* from the rendered {@link VisualLineMap} geometry — picking the nearest
|
|
1138
|
+
* visual line by `y`, then the nearest offset on it by `x`. Because a table
|
|
1139
|
+
* row's cells share one horizontal line band, this makes the whole width of a
|
|
1140
|
+
* row resolve into that row (rather than only the cell boxes), with no visible
|
|
1141
|
+
* layout change. It also lets a drag keep extending toward off-viewport points
|
|
1142
|
+
* (e.g. the pointer leaving the window), which the platform hit-test cannot
|
|
1143
|
+
* resolve. Set to `false` to fall back to the platform DOM hit-test.
|
|
1144
|
+
*/
|
|
1145
|
+
readonly geometricHitTest: ISettableObservable<boolean, void>;
|
|
572
1146
|
/**
|
|
573
1147
|
* Client coordinates → absolute source offset (any block). Used during
|
|
574
1148
|
* drag to keep extending the selection even when the pointer leaves the
|
|
575
|
-
* original block.
|
|
1149
|
+
* original block. Honours {@link geometricHitTest}.
|
|
576
1150
|
*/
|
|
577
1151
|
resolveOffsetFromPoint(point: Point2D): SourceOffset | undefined;
|
|
1152
|
+
/**
|
|
1153
|
+
* Resolve table-cell hits that have no measurable text run. Empty cells map
|
|
1154
|
+
* from their own box instead of snapping to a neighboring cell; element-only
|
|
1155
|
+
* content (for example an inactive image) maps through the hit element's view
|
|
1156
|
+
* node. Text-bearing cells keep the normal pixel-precise line-map/DOM path.
|
|
1157
|
+
*/
|
|
1158
|
+
private _resolveTableCellOffset;
|
|
578
1159
|
/**
|
|
579
1160
|
* Whether a client point falls on the rendered document content, as
|
|
580
1161
|
* opposed to the surrounding editor padding (the green area). Uses DOM
|
|
@@ -593,6 +1174,15 @@ export declare class EditorView extends Disposable {
|
|
|
593
1174
|
* is not read here, so there is no feedback loop into the render autorun.
|
|
594
1175
|
*/
|
|
595
1176
|
private _publishMeasurements;
|
|
1177
|
+
/**
|
|
1178
|
+
* Paint the diff highlights via the CSS Custom Highlight API: green over the
|
|
1179
|
+
* inserted/changed modified ranges (mapped on the document's own DOM), and
|
|
1180
|
+
* red over each {@link DiffDecorationViewNode}'s deleted ranges (mapped on
|
|
1181
|
+
* the decoration's own subtree). No DOM is mutated, so reconciliation and
|
|
1182
|
+
* editing are unaffected.
|
|
1183
|
+
*/
|
|
1184
|
+
private _paintDiff;
|
|
1185
|
+
private _clearDiff;
|
|
596
1186
|
}
|
|
597
1187
|
|
|
598
1188
|
export declare interface EditorViewOptions extends BlockViewOptions {
|
|
@@ -603,6 +1193,30 @@ export declare interface EditorViewOptions extends BlockViewOptions {
|
|
|
603
1193
|
* only) unless a theme class is supplied.
|
|
604
1194
|
*/
|
|
605
1195
|
readonly classNames?: readonly string[];
|
|
1196
|
+
/**
|
|
1197
|
+
* Whether to render the sticky edit/read-only toggle at the top-right edge
|
|
1198
|
+
* of the content. Defaults to `true`; set to `false` to omit it (e.g. in
|
|
1199
|
+
* fixtures that focus on selection rendering).
|
|
1200
|
+
*/
|
|
1201
|
+
readonly showReadonlyToggle?: boolean;
|
|
1202
|
+
/**
|
|
1203
|
+
* Controls "limited width mode". The observable yields the maximum content
|
|
1204
|
+
* width in pixels, or `undefined` to let the content fill the available
|
|
1205
|
+
* width. When the option is omitted, the width is capped at
|
|
1206
|
+
* {@link DEFAULT_LIMITED_WIDTH}px (limited mode is on by default).
|
|
1207
|
+
*
|
|
1208
|
+
* The cap and centering apply to an inner content container; the editor
|
|
1209
|
+
* root ({@link element}) always spans the full available width.
|
|
1210
|
+
*/
|
|
1211
|
+
readonly limitedWidth?: IObservable<number | undefined>;
|
|
1212
|
+
/**
|
|
1213
|
+
* Diff mode only: render every read-only original decoration in active
|
|
1214
|
+
* (source) form, so even whole-block removals expose their markdown markers
|
|
1215
|
+
* as real text. Used by the diff-coverage fixture to verify that every
|
|
1216
|
+
* changed original character is rendered somewhere; off in normal use, where
|
|
1217
|
+
* whole removals show a clean solid band.
|
|
1218
|
+
*/
|
|
1219
|
+
readonly diffDecorationsActive?: boolean;
|
|
606
1220
|
}
|
|
607
1221
|
|
|
608
1222
|
export declare class EmphasisAstNode extends AstNode {
|
|
@@ -670,14 +1284,39 @@ declare class GlueViewData {
|
|
|
670
1284
|
decorateNewline: boolean);
|
|
671
1285
|
}
|
|
672
1286
|
|
|
673
|
-
|
|
1287
|
+
/**
|
|
1288
|
+
* A single gutter marker: a source {@link OffsetRange} tagged with a
|
|
1289
|
+
* {@link GutterMarkerType}. The view resolves the range to the visual lines it
|
|
1290
|
+
* covers and paints a bar (or, for `deleted`, a wedge at the range position) in
|
|
1291
|
+
* the left gutter.
|
|
1292
|
+
*
|
|
1293
|
+
* A `deleted` marker is normally an empty range (`range.isEmpty`) sitting at the
|
|
1294
|
+
* boundary where the removed text used to be — there is nothing left to span,
|
|
1295
|
+
* so it is drawn as a caret between lines rather than a bar.
|
|
1296
|
+
*/
|
|
1297
|
+
export declare interface GutterMarker {
|
|
1298
|
+
readonly range: OffsetRange;
|
|
1299
|
+
readonly type: GutterMarkerType;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
/**
|
|
1303
|
+
* The kind of change a gutter marker represents, mirroring the three states a
|
|
1304
|
+
* source-control diff distinguishes (the git change markers in the editor
|
|
1305
|
+
* gutter): a freshly inserted region, an edited region, and a point where
|
|
1306
|
+
* content was removed.
|
|
1307
|
+
*/
|
|
1308
|
+
export declare type GutterMarkerType = 'added' | 'modified' | 'deleted';
|
|
1309
|
+
|
|
1310
|
+
export declare class HeadingAstNode extends BlockAstNodeBase {
|
|
674
1311
|
readonly level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
675
1312
|
readonly marker: MarkerAstNode;
|
|
676
1313
|
readonly content: readonly (InlineAstNode | GlueAstNode)[];
|
|
1314
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
677
1315
|
readonly kind = "heading";
|
|
678
|
-
constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[]);
|
|
1316
|
+
constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
679
1317
|
get children(): readonly AstNode[];
|
|
680
1318
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
1319
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): HeadingAstNode;
|
|
681
1320
|
protected _localEquals(o: this): boolean;
|
|
682
1321
|
}
|
|
683
1322
|
|
|
@@ -688,6 +1327,45 @@ declare class HeadingViewData {
|
|
|
688
1327
|
constructor(ast: HeadingAstNode, content: readonly AnyViewData[]);
|
|
689
1328
|
}
|
|
690
1329
|
|
|
1330
|
+
/**
|
|
1331
|
+
* The editor operations a clipboard strategy drives. The strategy never
|
|
1332
|
+
* touches the model or the DOM directly — it asks through this seam, so the
|
|
1333
|
+
* same strategy works regardless of how the editor is wired up.
|
|
1334
|
+
*/
|
|
1335
|
+
export declare interface IClipboardContext {
|
|
1336
|
+
/** The element that owns focus and receives clipboard/keyboard events. */
|
|
1337
|
+
readonly element: HTMLElement;
|
|
1338
|
+
/** The selected source text, or `undefined` when the selection is empty. */
|
|
1339
|
+
getSelectedText(): string | undefined;
|
|
1340
|
+
/** Delete the current selection (the cut half of cut). */
|
|
1341
|
+
deleteSelection(): void;
|
|
1342
|
+
/** Insert text at the caret, replacing any selection (the paste action). */
|
|
1343
|
+
insertText(text: string): void;
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
/**
|
|
1347
|
+
* How copy/cut/paste intent reaches the editor. Host environments deliver it
|
|
1348
|
+
* differently, so the controller owns no clipboard logic itself — it
|
|
1349
|
+
* {@link connect}s a strategy and lets it install whatever listeners it needs.
|
|
1350
|
+
*
|
|
1351
|
+
* Two implementations ship:
|
|
1352
|
+
* - {@link NativeClipboardStrategy} (default) reads the browser's native
|
|
1353
|
+
* `copy`/`cut`/`paste` events and their synchronous `clipboardData`.
|
|
1354
|
+
* - {@link AsyncClipboardStrategy} drives the async `navigator.clipboard` API
|
|
1355
|
+
* from Ctrl/Cmd+C/X/V keystrokes, for hosts (e.g. VS Code webviews) that
|
|
1356
|
+
* swallow the native clipboard events before they reach the editor.
|
|
1357
|
+
*/
|
|
1358
|
+
export declare interface IClipboardStrategy {
|
|
1359
|
+
/**
|
|
1360
|
+
* Wire up clipboard handling against `context`. The returned disposable
|
|
1361
|
+
* tears down every listener the strategy installed.
|
|
1362
|
+
*/
|
|
1363
|
+
connect(context: IClipboardContext): IDisposable;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
/** A live rendering of a {@link CommentsModel}. Dispose to unmount it. */
|
|
1367
|
+
export declare type ICommentsPresenter = IDisposable;
|
|
1368
|
+
|
|
691
1369
|
/** The Monarch language definitions the default highlighter wires up. */
|
|
692
1370
|
export declare interface IDefaultMonarchGrammars {
|
|
693
1371
|
typescript: unknown;
|
|
@@ -699,6 +1377,55 @@ export declare interface IDefaultMonarchGrammars {
|
|
|
699
1377
|
shell: unknown;
|
|
700
1378
|
}
|
|
701
1379
|
|
|
1380
|
+
/**
|
|
1381
|
+
* A live editor embedded in place of a fenced code block's *rendered* form.
|
|
1382
|
+
*
|
|
1383
|
+
* This is the internal seam between the block view and a concrete embedded
|
|
1384
|
+
* editor (e.g. an `<iframe>` speaking the web-editor protocol). The block view
|
|
1385
|
+
* only speaks string edits: it pushes the block's content down via
|
|
1386
|
+
* {@link setContent} and receives the editor's own changes back through
|
|
1387
|
+
* {@link onEdit} (set by the block view on each (re)construction, so it always
|
|
1388
|
+
* routes to the current AST node). The concrete implementation owns its DOM,
|
|
1389
|
+
* transport, and lifecycle.
|
|
1390
|
+
*
|
|
1391
|
+
* A single instance is adopted across re-renders (like the highlighter session)
|
|
1392
|
+
* so the underlying editor keeps its state across edits — see
|
|
1393
|
+
* {@link CodeBlockViewNode}.
|
|
1394
|
+
*/
|
|
1395
|
+
declare interface IEmbeddedCodeEditor {
|
|
1396
|
+
/** The element mounted as the block's rendered form. */
|
|
1397
|
+
readonly element: HTMLElement;
|
|
1398
|
+
/**
|
|
1399
|
+
* Document → editor. The block's content changed (from any source). Must be
|
|
1400
|
+
* idempotent: pushing the content the editor already holds is a no-op, which
|
|
1401
|
+
* is how edits the editor itself originated are prevented from echoing back.
|
|
1402
|
+
*/
|
|
1403
|
+
setContent(content: string): void;
|
|
1404
|
+
/**
|
|
1405
|
+
* Optional synchronous height (px) to reserve for `content` *before* the
|
|
1406
|
+
* editor has laid out. Return `undefined` to let the editor size itself
|
|
1407
|
+
* (the implementation may report its real height later). Lets a registration
|
|
1408
|
+
* avoid a layout jump when it can cheaply estimate the size from content.
|
|
1409
|
+
*/
|
|
1410
|
+
estimateHeight?(content: string): number | undefined;
|
|
1411
|
+
/**
|
|
1412
|
+
* Editor → document. Set by the block view on every (re)construction to
|
|
1413
|
+
* route the editor's own edits, expressed in the block's *content*
|
|
1414
|
+
* coordinates, to the current AST node.
|
|
1415
|
+
*/
|
|
1416
|
+
onEdit?: (edit: StringEdit) => void;
|
|
1417
|
+
dispose(): void;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
/** Creates an {@link IEmbeddedCodeEditor} for a fenced block, or opts out. */
|
|
1421
|
+
declare interface IEmbeddedCodeEditorFactory {
|
|
1422
|
+
/**
|
|
1423
|
+
* Return an editor for a fenced block of `language`, or `undefined` to fall
|
|
1424
|
+
* back to the default (highlighting / {@link BlockViewOptions.renderCustomCodeBlock}).
|
|
1425
|
+
*/
|
|
1426
|
+
create(language: string, initialContent: string): IEmbeddedCodeEditor | undefined;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
702
1429
|
export declare class ImageAstNode extends AstNode {
|
|
703
1430
|
readonly alt: string;
|
|
704
1431
|
readonly url: string;
|
|
@@ -782,6 +1509,21 @@ export declare const insertLineBreak: EditCommand;
|
|
|
782
1509
|
|
|
783
1510
|
export declare const insertParagraph: EditCommand;
|
|
784
1511
|
|
|
1512
|
+
/**
|
|
1513
|
+
* Context-aware Enter. The behaviour is chosen from the active block:
|
|
1514
|
+
* - paragraph / heading / thematic break — the "rich text" thing: at the
|
|
1515
|
+
* block's end arm a transient empty paragraph (see {@link SmartEnterResult});
|
|
1516
|
+
* elsewhere split into two paragraphs (`\n\n`).
|
|
1517
|
+
* - code block — insert a newline that preserves the current line's indentation,
|
|
1518
|
+
* staying inside the fence.
|
|
1519
|
+
* - block quote — continue the quote (`\n> `); an empty quote line exits it.
|
|
1520
|
+
* - list — continue the list with the next marker (incrementing ordered
|
|
1521
|
+
* numbers, re-emitting task checkboxes); an empty item exits the list.
|
|
1522
|
+
* A non-collapsed selection, or any other block, falls back to a plain soft line
|
|
1523
|
+
* break, preserving today's behaviour.
|
|
1524
|
+
*/
|
|
1525
|
+
export declare const insertSmartEnter: (ctx: CursorCommandContext) => SmartEnterResult;
|
|
1526
|
+
|
|
785
1527
|
export declare function insertText(text: string): EditCommand;
|
|
786
1528
|
|
|
787
1529
|
/**
|
|
@@ -886,14 +1628,16 @@ declare class LinkViewData {
|
|
|
886
1628
|
constructor(ast: LinkAstNode, content: readonly AnyViewData[]);
|
|
887
1629
|
}
|
|
888
1630
|
|
|
889
|
-
export declare class ListAstNode extends
|
|
1631
|
+
export declare class ListAstNode extends BlockAstNodeBase {
|
|
890
1632
|
readonly ordered: boolean;
|
|
891
1633
|
readonly content: readonly (ListItemAstNode | GlueAstNode)[];
|
|
1634
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
892
1635
|
readonly kind = "list";
|
|
893
|
-
constructor(ordered: boolean, content: readonly (ListItemAstNode | GlueAstNode)[]);
|
|
1636
|
+
constructor(ordered: boolean, content: readonly (ListItemAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
894
1637
|
get children(): readonly AstNode[];
|
|
895
1638
|
get items(): readonly ListItemAstNode[];
|
|
896
1639
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
1640
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): ListAstNode;
|
|
897
1641
|
protected _localEquals(o: this): boolean;
|
|
898
1642
|
}
|
|
899
1643
|
|
|
@@ -907,6 +1651,7 @@ export declare class ListItemAstNode extends AstNode {
|
|
|
907
1651
|
get children(): readonly AstNode[];
|
|
908
1652
|
get blocks(): readonly BlockAstNode[];
|
|
909
1653
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
1654
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): ListItemAstNode;
|
|
910
1655
|
protected _localEquals(o: this): boolean;
|
|
911
1656
|
}
|
|
912
1657
|
|
|
@@ -960,13 +1705,15 @@ declare class MarkerViewData {
|
|
|
960
1705
|
constructor(ast: MarkerAstNode, visible: boolean);
|
|
961
1706
|
}
|
|
962
1707
|
|
|
963
|
-
export declare class MathBlockAstNode extends
|
|
1708
|
+
export declare class MathBlockAstNode extends BlockAstNodeBase {
|
|
964
1709
|
readonly content: readonly (MarkerAstNode | GlueAstNode)[];
|
|
1710
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
965
1711
|
readonly kind = "mathBlock";
|
|
966
|
-
constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
|
|
1712
|
+
constructor(content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
967
1713
|
get children(): readonly AstNode[];
|
|
968
1714
|
get code(): MarkerAstNode | undefined;
|
|
969
1715
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
1716
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): MathBlockAstNode;
|
|
970
1717
|
}
|
|
971
1718
|
|
|
972
1719
|
declare class MathBlockViewData {
|
|
@@ -1129,6 +1876,26 @@ export declare class MonacoSyntaxHighlighter implements ISyntaxHighlighter {
|
|
|
1129
1876
|
private _tokenizerFor;
|
|
1130
1877
|
}
|
|
1131
1878
|
|
|
1879
|
+
/**
|
|
1880
|
+
* Default strategy: handle the browser's native `copy`/`cut`/`paste` events,
|
|
1881
|
+
* reading and writing the synchronous {@link ClipboardEvent.clipboardData}.
|
|
1882
|
+
* This is the standard rich-editor approach and works wherever the browser
|
|
1883
|
+
* actually dispatches those events to the focused element (e.g. a standalone
|
|
1884
|
+
* web page).
|
|
1885
|
+
*/
|
|
1886
|
+
export declare class NativeClipboardStrategy implements IClipboardStrategy {
|
|
1887
|
+
connect(context: IClipboardContext): IDisposable;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
declare interface NestedItem {
|
|
1891
|
+
readonly kind: 'nested';
|
|
1892
|
+
readonly original: AstNode;
|
|
1893
|
+
readonly originalStart: number;
|
|
1894
|
+
readonly modified: AstNode;
|
|
1895
|
+
readonly modifiedStart: number;
|
|
1896
|
+
readonly children: readonly DiffItem[];
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1132
1899
|
/**
|
|
1133
1900
|
* Move the cursor one position left or right, skipping over hidden marker
|
|
1134
1901
|
* ranges in inactive blocks (and inactive items of an active list).
|
|
@@ -1164,12 +1931,14 @@ export declare class OffsetRange {
|
|
|
1164
1931
|
toString(): string;
|
|
1165
1932
|
}
|
|
1166
1933
|
|
|
1167
|
-
export declare class ParagraphAstNode extends
|
|
1934
|
+
export declare class ParagraphAstNode extends BlockAstNodeBase {
|
|
1168
1935
|
readonly content: readonly (InlineAstNode | GlueAstNode)[];
|
|
1936
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
1169
1937
|
readonly kind = "paragraph";
|
|
1170
|
-
constructor(content: readonly (InlineAstNode | GlueAstNode)[]);
|
|
1938
|
+
constructor(content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
1171
1939
|
get children(): readonly AstNode[];
|
|
1172
1940
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
1941
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): ParagraphAstNode;
|
|
1173
1942
|
}
|
|
1174
1943
|
|
|
1175
1944
|
declare class ParagraphViewData {
|
|
@@ -1179,6 +1948,45 @@ declare class ParagraphViewData {
|
|
|
1179
1948
|
constructor(ast: ParagraphAstNode, content: readonly AnyViewData[]);
|
|
1180
1949
|
}
|
|
1181
1950
|
|
|
1951
|
+
/**
|
|
1952
|
+
* A *transient* editing state: the empty paragraph the user conjured by
|
|
1953
|
+
* pressing Enter at the end of a paragraph. Markdown has no empty-paragraph
|
|
1954
|
+
* node, so this never lives in {@link EditorModel.sourceText} or the parsed
|
|
1955
|
+
* {@link EditorModel.document} — it is pure edit intent that the view renders
|
|
1956
|
+
* as a synthetic blank line and that the controller either *materializes* (the
|
|
1957
|
+
* user types) or *cancels* (the user navigates away / backspaces).
|
|
1958
|
+
*/
|
|
1959
|
+
declare interface PendingParagraph {
|
|
1960
|
+
/** The paragraph the blank line is rendered directly after. */
|
|
1961
|
+
readonly anchorBlock: BlockAstNode;
|
|
1962
|
+
/**
|
|
1963
|
+
* Source region rewritten when the pending paragraph is materialized — the
|
|
1964
|
+
* gap between {@link anchorBlock}'s text and whatever follows it.
|
|
1965
|
+
*/
|
|
1966
|
+
readonly replaceRange: OffsetRange;
|
|
1967
|
+
/** Whether {@link replaceRange} ends at the end of the document. */
|
|
1968
|
+
readonly atEof: boolean;
|
|
1969
|
+
/**
|
|
1970
|
+
* A throwaway AST node that exists only to give the synthetic view child a
|
|
1971
|
+
* stable identity across render frames (the view pairs nodes by `ast.id`).
|
|
1972
|
+
* It is never part of {@link document}.
|
|
1973
|
+
*/
|
|
1974
|
+
readonly syntheticAst: ParagraphAstNode;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
/**
|
|
1978
|
+
* View-data for the transient empty paragraph (see `PendingParagraph` in the
|
|
1979
|
+
* model). It carries only the throwaway {@link ParagraphAstNode} that gives the
|
|
1980
|
+
* rendered blank line a stable identity across frames; it has no content and is
|
|
1981
|
+
* never measured or part of the selection geometry — the caret is positioned
|
|
1982
|
+
* over it via a dedicated rect, not via the visual-line map.
|
|
1983
|
+
*/
|
|
1984
|
+
declare class PendingParagraphViewData {
|
|
1985
|
+
readonly ast: ParagraphAstNode;
|
|
1986
|
+
readonly kind = "pendingParagraph";
|
|
1987
|
+
constructor(ast: ParagraphAstNode);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1182
1990
|
/**
|
|
1183
1991
|
* Immutable point in 2D space, in CSS-pixel client coordinates.
|
|
1184
1992
|
*/
|
|
@@ -1218,6 +2026,23 @@ export declare class Rect2D {
|
|
|
1218
2026
|
translate(dx: number, dy: number): Rect2D;
|
|
1219
2027
|
}
|
|
1220
2028
|
|
|
2029
|
+
declare interface RemovedItem {
|
|
2030
|
+
readonly kind: 'removed';
|
|
2031
|
+
readonly node: AstNode;
|
|
2032
|
+
readonly originalStart: number;
|
|
2033
|
+
readonly deletedLocal: readonly AnnotatedRange[];
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
declare interface ReplacedItem {
|
|
2037
|
+
readonly kind: 'replaced';
|
|
2038
|
+
readonly original: AstNode;
|
|
2039
|
+
readonly originalStart: number;
|
|
2040
|
+
readonly modified: AstNode;
|
|
2041
|
+
readonly modifiedStart: number;
|
|
2042
|
+
readonly insertedLocal: readonly AnnotatedRange[];
|
|
2043
|
+
readonly deletedLocal: readonly AnnotatedRange[];
|
|
2044
|
+
}
|
|
2045
|
+
|
|
1221
2046
|
export declare const selectAll: SelectionCommand;
|
|
1222
2047
|
|
|
1223
2048
|
export declare function selectBlock(ctx: CursorCommandContext, blockRange: OffsetRange): Selection_2;
|
|
@@ -1245,6 +2070,15 @@ export declare interface SelectionBlock {
|
|
|
1245
2070
|
readonly absoluteStart: number;
|
|
1246
2071
|
readonly viewNode: ViewNode;
|
|
1247
2072
|
readonly element: HTMLElement;
|
|
2073
|
+
/**
|
|
2074
|
+
* The block's horizontal scroll viewport. Equal to {@link element} for every
|
|
2075
|
+
* block whose element is itself the `overflow-x: auto` scroller (code, math,
|
|
2076
|
+
* unhandled), but the wrapping `.md-table-wrapper` for a table, whose
|
|
2077
|
+
* {@link element} is the content-sized inner `<table>`. Only
|
|
2078
|
+
* {@link blockViewportClip} needs the scroll box; connector/rect geometry
|
|
2079
|
+
* still uses {@link element}.
|
|
2080
|
+
*/
|
|
2081
|
+
readonly scrollElement: HTMLElement;
|
|
1248
2082
|
}
|
|
1249
2083
|
|
|
1250
2084
|
export declare type SelectionCommand = (ctx: CursorCommandContext, offset: SourceOffset) => Selection_2;
|
|
@@ -1296,6 +2130,25 @@ export declare class SelectionViewRendering {
|
|
|
1296
2130
|
|
|
1297
2131
|
export declare const selectWord: SelectionCommand;
|
|
1298
2132
|
|
|
2133
|
+
/**
|
|
2134
|
+
* The outcome of {@link insertSmartEnter}: either a concrete source edit (the
|
|
2135
|
+
* ordinary cases), or a request to arm a transient empty paragraph (Enter at
|
|
2136
|
+
* the very end of a paragraph), which the controller turns into
|
|
2137
|
+
* {@link EditorModel.armPendingParagraph} rather than a source edit. Modelling
|
|
2138
|
+
* the empty paragraph as state instead of source keeps the document valid
|
|
2139
|
+
* Markdown — which has no empty-paragraph node — until the user actually types.
|
|
2140
|
+
*/
|
|
2141
|
+
export declare type SmartEnterResult = {
|
|
2142
|
+
readonly kind: 'edit';
|
|
2143
|
+
readonly edit: StringEdit;
|
|
2144
|
+
readonly selection: Selection_2;
|
|
2145
|
+
} | {
|
|
2146
|
+
readonly kind: 'pending';
|
|
2147
|
+
readonly anchorBlock: BlockAstNode;
|
|
2148
|
+
readonly replaceRange: OffsetRange;
|
|
2149
|
+
readonly atEof: boolean;
|
|
2150
|
+
};
|
|
2151
|
+
|
|
1299
2152
|
/**
|
|
1300
2153
|
* A run of {@link Token}s together with the exact {@link OffsetRange} they
|
|
1301
2154
|
* cover.
|
|
@@ -1311,6 +2164,26 @@ export declare interface SnapshotTokens {
|
|
|
1311
2164
|
|
|
1312
2165
|
export declare type SourceOffset = number;
|
|
1313
2166
|
|
|
2167
|
+
export declare abstract class StackedCommentsPresenter extends Disposable implements ICommentsPresenter {
|
|
2168
|
+
protected readonly model: CommentsModel;
|
|
2169
|
+
protected readonly view: EditorView;
|
|
2170
|
+
protected readonly context?: CommentsPresenterContext | undefined;
|
|
2171
|
+
private readonly _layer;
|
|
2172
|
+
private readonly _entries;
|
|
2173
|
+
private _order;
|
|
2174
|
+
constructor(model: CommentsModel, view: EditorView, context?: CommentsPresenterContext | undefined);
|
|
2175
|
+
/** Build the card DOM for a comment. Called once per new comment. */
|
|
2176
|
+
protected abstract createWidget(comment: Comment_2): StackWidget;
|
|
2177
|
+
private _reconcile;
|
|
2178
|
+
private _relayout;
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
/** The minimal widget contract a subclass must produce. */
|
|
2182
|
+
export declare interface StackWidget {
|
|
2183
|
+
readonly element: HTMLElement;
|
|
2184
|
+
dispose(): void;
|
|
2185
|
+
}
|
|
2186
|
+
|
|
1314
2187
|
export declare class StrikethroughAstNode extends AstNode {
|
|
1315
2188
|
readonly openMarker: MarkerAstNode;
|
|
1316
2189
|
readonly content: readonly (InlineAstNode | GlueAstNode)[];
|
|
@@ -1381,16 +2254,18 @@ declare class StrongViewData {
|
|
|
1381
2254
|
constructor(ast: StrongAstNode, content: readonly AnyViewData[]);
|
|
1382
2255
|
}
|
|
1383
2256
|
|
|
1384
|
-
export declare class TableAstNode extends
|
|
2257
|
+
export declare class TableAstNode extends BlockAstNodeBase {
|
|
1385
2258
|
readonly content: readonly (TableRowAstNode | GlueAstNode)[];
|
|
2259
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
1386
2260
|
readonly kind = "table";
|
|
1387
|
-
constructor(content: readonly (TableRowAstNode | GlueAstNode)[]);
|
|
2261
|
+
constructor(content: readonly (TableRowAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
1388
2262
|
get children(): readonly AstNode[];
|
|
1389
2263
|
private get _rows();
|
|
1390
2264
|
get headerRow(): TableRowAstNode | undefined;
|
|
1391
2265
|
get delimiterRow(): TableRowAstNode | undefined;
|
|
1392
2266
|
get bodyRows(): readonly TableRowAstNode[];
|
|
1393
2267
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
2268
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): TableAstNode;
|
|
1394
2269
|
}
|
|
1395
2270
|
|
|
1396
2271
|
export declare class TableCellAstNode extends AstNode {
|
|
@@ -1472,13 +2347,15 @@ declare class TextViewData {
|
|
|
1472
2347
|
constructor(ast: TextAstNode, showWhitespace: boolean, leftWordBoundary?: boolean, rightWordBoundary?: boolean);
|
|
1473
2348
|
}
|
|
1474
2349
|
|
|
1475
|
-
export declare class ThematicBreakAstNode extends
|
|
2350
|
+
export declare class ThematicBreakAstNode extends BlockAstNodeBase {
|
|
1476
2351
|
readonly content: readonly (MarkerAstNode | GlueAstNode)[];
|
|
2352
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
1477
2353
|
readonly kind = "thematicBreak";
|
|
1478
|
-
constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
|
|
2354
|
+
constructor(content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
1479
2355
|
get children(): readonly AstNode[];
|
|
1480
2356
|
get marker(): MarkerAstNode | undefined;
|
|
1481
2357
|
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
2358
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): ThematicBreakAstNode;
|
|
1482
2359
|
}
|
|
1483
2360
|
|
|
1484
2361
|
declare class ThematicBreakViewData {
|
|
@@ -1511,6 +2388,47 @@ export declare class Token {
|
|
|
1511
2388
|
className: string | undefined);
|
|
1512
2389
|
}
|
|
1513
2390
|
|
|
2391
|
+
declare interface UnchangedItem {
|
|
2392
|
+
readonly kind: 'unchanged';
|
|
2393
|
+
/** The modified-side node (identical in content to the original). */
|
|
2394
|
+
readonly node: AstNode;
|
|
2395
|
+
readonly modifiedStart: number;
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
/**
|
|
2399
|
+
* A block whose token type the parser does not understand (a setext heading, a
|
|
2400
|
+
* frontmatter fence, any future/extension construct). Rather than dropping the
|
|
2401
|
+
* span — which would demote its text to invisible glue — the parser captures the
|
|
2402
|
+
* whole source range verbatim as a single {@link MarkerAstNode} of kind
|
|
2403
|
+
* `content` and records the originating micromark {@link tokenType}, so the view
|
|
2404
|
+
* can render it as raw, editable text with an "unhandled" affordance. Offsets
|
|
2405
|
+
* stay sound: `content` tiles the block's full source span exactly.
|
|
2406
|
+
*/
|
|
2407
|
+
declare class UnhandledBlockAstNode extends BlockAstNodeBase {
|
|
2408
|
+
readonly tokenType: string;
|
|
2409
|
+
readonly content: readonly (MarkerAstNode | GlueAstNode)[];
|
|
2410
|
+
readonly leadingTrivia?: GlueAstNode | undefined;
|
|
2411
|
+
readonly kind = "unhandledBlock";
|
|
2412
|
+
constructor(tokenType: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
|
|
2413
|
+
get children(): readonly AstNode[];
|
|
2414
|
+
get code(): MarkerAstNode | undefined;
|
|
2415
|
+
mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
|
|
2416
|
+
withLeadingTrivia(trivia: GlueAstNode | undefined): UnhandledBlockAstNode;
|
|
2417
|
+
protected _localEquals(o: this): boolean;
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
/**
|
|
2421
|
+
* View-data for an {@link UnhandledBlockAstNode}. It has no active/inactive
|
|
2422
|
+
* split — the raw source *is* both the source and the rendered form — so it
|
|
2423
|
+
* carries no `showMarkup` flag; the renderer always shows the verbatim text.
|
|
2424
|
+
*/
|
|
2425
|
+
declare class UnhandledBlockViewData {
|
|
2426
|
+
readonly ast: UnhandledBlockAstNode;
|
|
2427
|
+
readonly content: readonly AnyViewData[];
|
|
2428
|
+
readonly kind = "unhandledBlock";
|
|
2429
|
+
constructor(ast: UnhandledBlockAstNode, content: readonly AnyViewData[]);
|
|
2430
|
+
}
|
|
2431
|
+
|
|
1514
2432
|
/**
|
|
1515
2433
|
* Immutable view of an AST node. Pairs `ast` with its rendered `dom` and a
|
|
1516
2434
|
* mirror of `ast.children` as ViewNode children. Source offsets are NEVER
|
|
@@ -1575,10 +2493,12 @@ export declare class ViewNode extends Disposable {
|
|
|
1575
2493
|
/**
|
|
1576
2494
|
* Map a DOM hit that lands on THIS node's own representation into a source
|
|
1577
2495
|
* range in this node's local space `[0, ast.length)`. Polymorphic: a text
|
|
1578
|
-
* leaf maps the caret offset 1:1
|
|
1579
|
-
* an image, a hidden marker)
|
|
1580
|
-
*
|
|
1581
|
-
*
|
|
2496
|
+
* leaf maps the caret offset 1:1. For an element hit — an element-only node
|
|
2497
|
+
* (KaTeX math, `<hr>`, an image, a hidden marker) or a wrapper/container
|
|
2498
|
+
* element — the platform reports a child-index offset, not a text caret, so
|
|
2499
|
+
* there is no internal mapping to honour: it snaps to the node's nearer
|
|
2500
|
+
* edge, `offset 0` (the "before" side) → start, any `offset >= 1` (the
|
|
2501
|
+
* "after" side) → end. Subclasses may override for finer control.
|
|
1582
2502
|
*/
|
|
1583
2503
|
getLocalSourceRange(pos: DomPosition): OffsetRange;
|
|
1584
2504
|
/**
|
|
@@ -1635,16 +2555,29 @@ export declare class VisualLine {
|
|
|
1635
2555
|
*/
|
|
1636
2556
|
sourceDistanceTo(offset: SourceOffset): number;
|
|
1637
2557
|
/**
|
|
1638
|
-
* x of the caret position before `offset` on this line.
|
|
1639
|
-
*
|
|
1640
|
-
*
|
|
1641
|
-
*
|
|
2558
|
+
* x of the caret position before `offset` on this line.
|
|
2559
|
+
*
|
|
2560
|
+
* The runs tile the source but are stored in paint order, not sorted by
|
|
2561
|
+
* source offset (hidden-marker runs are appended last). So this scans all
|
|
2562
|
+
* runs rather than assuming any ordering:
|
|
2563
|
+
*
|
|
2564
|
+
* - If some run *covers* `offset`, its own geometry places the caret
|
|
2565
|
+
* (exact glyph boundary for text runs). In the active, markers-visible
|
|
2566
|
+
* form every offset is covered, so this branch keeps distinct offsets
|
|
2567
|
+
* distinct.
|
|
2568
|
+
* - Otherwise `offset` sits in a gap — a hidden inline marker such as the
|
|
2569
|
+
* `**` of `**bold**`, or before/after the painted text. It snaps to the
|
|
2570
|
+
* seam between the source-nearest runs on either side: the right edge of
|
|
2571
|
+
* the closest run ending at/before `offset`, else the left edge of the
|
|
2572
|
+
* closest run starting at/after it. A hidden marker collapses to zero
|
|
2573
|
+
* width, so both edges coincide at the seam.
|
|
1642
2574
|
*/
|
|
1643
2575
|
xAtOffset(offset: SourceOffset): number;
|
|
1644
2576
|
/**
|
|
1645
2577
|
* Snap `x` to the nearest offset on this line. If `x` falls inside a
|
|
1646
|
-
* run, the offset
|
|
1647
|
-
*
|
|
2578
|
+
* run, the run resolves the offset (exact glyph boundary for text runs,
|
|
2579
|
+
* nearer edge for source-less runs); otherwise it snaps to the closer
|
|
2580
|
+
* edge of the nearest run.
|
|
1648
2581
|
*/
|
|
1649
2582
|
offsetAtX(x: number): SourceOffset;
|
|
1650
2583
|
}
|
|
@@ -1732,8 +2665,14 @@ export declare class VisualLineMap {
|
|
|
1732
2665
|
* When constructed with a {@link VisualRunSource}, `xAtOffset` returns the
|
|
1733
2666
|
* pixel-exact x of the caret before character `offset` by measuring the
|
|
1734
2667
|
* prefix `[textNodeStart, textNodeStart + (offset - sourceStart))` with a
|
|
1735
|
-
* DOM `Range`.
|
|
1736
|
-
*
|
|
2668
|
+
* DOM `Range`.
|
|
2669
|
+
*
|
|
2670
|
+
* A source-less run has no per-offset geometry: it either represents an
|
|
2671
|
+
* element-only block (KaTeX math, a mermaid/custom diagram, an image, an
|
|
2672
|
+
* inactive `<hr>`) whose box does not correspond to source offsets, or a
|
|
2673
|
+
* hand-built run in a test. Either way it maps between offsets and x by
|
|
2674
|
+
* snapping to the nearer edge of {@link rect} rather than fabricating
|
|
2675
|
+
* interior positions.
|
|
1737
2676
|
*/
|
|
1738
2677
|
export declare class VisualRun {
|
|
1739
2678
|
readonly sourceRange: OffsetRange;
|
|
@@ -1751,14 +2690,15 @@ export declare class VisualRun {
|
|
|
1751
2690
|
|
|
1752
2691
|
/**
|
|
1753
2692
|
* The DOM source of a {@link VisualRun}. When set, `xAtOffset` and
|
|
1754
|
-
* `offsetAtX` measure exact glyph positions via `Range.getBoundingClientRect
|
|
1755
|
-
*
|
|
1756
|
-
*
|
|
1757
|
-
*
|
|
1758
|
-
* wrong character.
|
|
2693
|
+
* `offsetAtX` measure exact glyph positions via `Range.getBoundingClientRect`.
|
|
2694
|
+
* This matters for proportional fonts where character widths differ a lot
|
|
2695
|
+
* (e.g. `m` vs `i`): a caret placed by anything coarser than real glyph
|
|
2696
|
+
* measurement lands several pixels inside the wrong character.
|
|
1759
2697
|
*
|
|
1760
|
-
*
|
|
1761
|
-
*
|
|
2698
|
+
* A run without a source has no per-offset geometry, so it maps between
|
|
2699
|
+
* offsets and x by snapping to the nearer run edge. Real text runs always
|
|
2700
|
+
* carry a source; source-less runs are element-only blocks (see
|
|
2701
|
+
* {@link _appendElementBlockRun}) and hand-built runs in tests.
|
|
1762
2702
|
*/
|
|
1763
2703
|
declare interface VisualRunSource {
|
|
1764
2704
|
readonly textNode: Text;
|
|
@@ -1766,4 +2706,12 @@ declare interface VisualRunSource {
|
|
|
1766
2706
|
readonly textNodeStart: number;
|
|
1767
2707
|
}
|
|
1768
2708
|
|
|
2709
|
+
export declare class VscodeStackedCommentsView extends StackedCommentsPresenter {
|
|
2710
|
+
protected createWidget(comment: Comment_2): StackWidget;
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
export declare class VsCodeV2CommentsView extends StackedCommentsPresenter {
|
|
2714
|
+
protected createWidget(comment: Comment_2): StackWidget;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
1769
2717
|
export { }
|