@dxos/ui-editor 0.8.4-main.2244d791bb → 0.8.4-main.3fbcb4aa9b
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/lib/browser/index.mjs +1847 -1031
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +26 -6
- package/dist/lib/browser/types/index.mjs.map +4 -4
- package/dist/lib/node-esm/index.mjs +1848 -1031
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +27 -6
- package/dist/lib/node-esm/types/index.mjs.map +4 -4
- package/dist/types/src/defaults.d.ts +4 -10
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/auto-scroll.d.ts +13 -14
- package/dist/types/src/extensions/auto-scroll.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +5 -2
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +4 -3
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/focus.d.ts +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +3 -2
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +3 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -1
- package/dist/types/src/extensions/preview/preview.d.ts +2 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/replacer.d.ts.map +1 -1
- package/dist/types/src/extensions/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scroller.d.ts +68 -0
- package/dist/types/src/extensions/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +4 -1
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +28 -8
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/index.d.ts +0 -2
- package/dist/types/src/styles/index.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts +15 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +4 -4
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts +1 -1
- package/dist/types/src/util/cursor.d.ts.map +1 -1
- package/dist/types/src/util/debug.d.ts.map +1 -1
- package/dist/types/src/util/decorations.d.ts.map +1 -1
- package/dist/types/src/util/dom.d.ts.map +1 -1
- package/dist/types/src/util/facet.d.ts.map +1 -1
- package/dist/types/src/util/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +36 -39
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/auto-scroll.ts +149 -120
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +37 -11
- package/src/extensions/automerge/automerge.ts +5 -7
- package/src/extensions/blocks.ts +5 -5
- package/src/extensions/comments.ts +5 -6
- package/src/extensions/dnd.ts +2 -2
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +32 -15
- package/src/extensions/folding.ts +5 -22
- package/src/extensions/index.ts +3 -2
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +15 -12
- package/src/extensions/markdown/highlight.ts +15 -7
- package/src/extensions/markdown/link.ts +27 -33
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +42 -9
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +3 -4
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +55 -8
- package/src/extensions/scroll-past-end.ts +32 -0
- package/src/extensions/scroller.ts +256 -0
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +186 -35
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/index.ts +0 -2
- package/src/styles/theme.ts +115 -37
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +1 -2
- package/dist/lib/browser/chunk-HL3YF6WC.mjs +0 -22
- package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs +0 -24
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +0 -7
- package/dist/types/src/extensions/smooth-scroll.d.ts +0 -78
- package/dist/types/src/extensions/smooth-scroll.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/streamer.d.ts +0 -12
- package/dist/types/src/extensions/tags/streamer.d.ts.map +0 -1
- package/dist/types/src/extensions/typewriter.d.ts +0 -10
- package/dist/types/src/extensions/typewriter.d.ts.map +0 -1
- package/dist/types/src/styles/markdown.d.ts +0 -8
- package/dist/types/src/styles/markdown.d.ts.map +0 -1
- package/dist/types/src/styles/tokens.d.ts +0 -3
- package/dist/types/src/styles/tokens.d.ts.map +0 -1
- package/src/extensions/smooth-scroll.ts +0 -195
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
- package/src/styles/markdown.ts +0 -26
- package/src/styles/tokens.ts +0 -17
|
@@ -1,29 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EditorInputMode,
|
|
3
|
-
EditorInputModes,
|
|
4
|
-
EditorViewMode,
|
|
5
|
-
EditorViewModes
|
|
6
|
-
} from "./chunk-HL3YF6WC.mjs";
|
|
7
|
-
|
|
8
1
|
// src/index.ts
|
|
9
|
-
import { EditorState as
|
|
10
|
-
import { EditorView as
|
|
2
|
+
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
3
|
+
import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
|
|
11
4
|
import { tags as tags2 } from "@lezer/highlight";
|
|
12
5
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
13
6
|
|
|
14
7
|
// src/defaults.ts
|
|
15
8
|
import { mx } from "@dxos/ui-theme";
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
var editorClassNames = (role) => mx("dx-attention-surface p-0.5 data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
10
|
+
var documentSlots = {
|
|
11
|
+
content: {
|
|
12
|
+
/**
|
|
13
|
+
* CodeMirror content width.
|
|
14
|
+
* 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
|
|
15
|
+
* 50rem = 800px. Maximum content width for solo mode.
|
|
16
|
+
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
17
|
+
*/
|
|
18
|
+
className: mx(
|
|
19
|
+
// Inline-size container for widget sizing (children use `max-w-[100cqi]`).
|
|
20
|
+
// NOTE: Use inline-size, not full size containment — `container-type: size` on the
|
|
21
|
+
// editor content breaks CodeMirror's viewport measurement, leaving blank gaps during
|
|
22
|
+
// scroll until a click forces a re-measure.
|
|
23
|
+
"dx-inline-size-container",
|
|
24
|
+
// Wider margin for web (vs. mobile).
|
|
25
|
+
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
26
|
+
"mx-auto! w-full"
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var compactSlots = {
|
|
31
|
+
content: {
|
|
32
|
+
className: "mx-2!"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var mobileSlots = {
|
|
21
36
|
content: {
|
|
22
|
-
className:
|
|
37
|
+
className: "mx-2!"
|
|
23
38
|
}
|
|
24
39
|
};
|
|
25
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
26
|
-
var stackItemContentEditorClassNames = (role) => mx("p-0.5 dx-focus-ring-inset attention-surface data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
|
|
27
40
|
|
|
28
41
|
// src/extensions/annotations.ts
|
|
29
42
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
@@ -58,7 +71,7 @@ var annotations = ({ match } = {}) => {
|
|
|
58
71
|
".cm-annotation": {
|
|
59
72
|
textDecoration: "underline",
|
|
60
73
|
textDecorationStyle: "wavy",
|
|
61
|
-
textDecorationColor: "var(--
|
|
74
|
+
textDecorationColor: "var(--color-error-text)"
|
|
62
75
|
}
|
|
63
76
|
})
|
|
64
77
|
];
|
|
@@ -207,7 +220,7 @@ var singleValueFacet = (defaultValue) => Facet.define({
|
|
|
207
220
|
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
208
221
|
var defaultCursorConverter = {
|
|
209
222
|
toCursor: (position) => position.toString(),
|
|
210
|
-
fromCursor: (
|
|
223
|
+
fromCursor: (cursor) => parseInt(cursor)
|
|
211
224
|
};
|
|
212
225
|
var Cursor = class _Cursor {
|
|
213
226
|
static converter = singleValueFacet(defaultCursorConverter);
|
|
@@ -220,9 +233,9 @@ var Cursor = class _Cursor {
|
|
|
220
233
|
to
|
|
221
234
|
].join(":");
|
|
222
235
|
};
|
|
223
|
-
static getRangeFromCursor = (state,
|
|
236
|
+
static getRangeFromCursor = (state, cursor) => {
|
|
224
237
|
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
225
|
-
const parts =
|
|
238
|
+
const parts = cursor.split(":");
|
|
226
239
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
227
240
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
228
241
|
return from !== void 0 && to !== void 0 ? {
|
|
@@ -258,12 +271,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
258
271
|
} catch (err) {
|
|
259
272
|
log.catch(err, {
|
|
260
273
|
label
|
|
261
|
-
}, {
|
|
262
|
-
F: __dxlog_file,
|
|
263
|
-
L: 20,
|
|
264
|
-
S: void 0,
|
|
265
|
-
C: (f, a) => f(...a)
|
|
266
|
-
});
|
|
274
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
267
275
|
}
|
|
268
276
|
};
|
|
269
277
|
};
|
|
@@ -289,12 +297,7 @@ var logChanges = (trs) => {
|
|
|
289
297
|
if (changes.length) {
|
|
290
298
|
log("changes", {
|
|
291
299
|
changes
|
|
292
|
-
}, {
|
|
293
|
-
F: __dxlog_file,
|
|
294
|
-
L: 54,
|
|
295
|
-
S: void 0,
|
|
296
|
-
C: (f, a) => f(...a)
|
|
297
|
-
});
|
|
300
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
298
301
|
}
|
|
299
302
|
};
|
|
300
303
|
|
|
@@ -360,30 +363,37 @@ var insertAtLineStart = (view, from, insert) => {
|
|
|
360
363
|
};
|
|
361
364
|
|
|
362
365
|
// src/extensions/autocomplete/placeholder.ts
|
|
363
|
-
var placeholder = ({ content, delay = 3e3 }) => {
|
|
366
|
+
var placeholder = ({ content, delay = 3e3, focusOnly = false }) => {
|
|
364
367
|
const plugin = ViewPlugin3.fromClass(class {
|
|
365
368
|
_timeout;
|
|
366
369
|
_decorations = Decoration3.none;
|
|
367
370
|
update(update2) {
|
|
371
|
+
if (!update2.docChanged && !update2.selectionSet && !update2.focusChanged) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
368
374
|
if (this._timeout) {
|
|
369
375
|
window.clearTimeout(this._timeout);
|
|
370
376
|
this._timeout = void 0;
|
|
371
377
|
}
|
|
378
|
+
this._decorations = Decoration3.none;
|
|
379
|
+
if (focusOnly && !update2.view.hasFocus) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
372
382
|
const activeLine = update2.view.state.doc.lineAt(update2.view.state.selection.main.head);
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const lineStart = activeLine.from;
|
|
376
|
-
this._timeout = setTimeout(() => {
|
|
377
|
-
this._decorations = Decoration3.set([
|
|
378
|
-
Decoration3.widget({
|
|
379
|
-
widget: new PlaceholderWidget(content),
|
|
380
|
-
side: 1
|
|
381
|
-
}).range(lineStart)
|
|
382
|
-
]);
|
|
383
|
-
update2.view.update([]);
|
|
384
|
-
}, delay);
|
|
383
|
+
if (activeLine.text.trim() !== "") {
|
|
384
|
+
return;
|
|
385
385
|
}
|
|
386
|
-
|
|
386
|
+
const lineStart = activeLine.from;
|
|
387
|
+
const view = update2.view;
|
|
388
|
+
this._timeout = setTimeout(() => {
|
|
389
|
+
this._decorations = Decoration3.set([
|
|
390
|
+
Decoration3.widget({
|
|
391
|
+
widget: new PlaceholderWidget(content),
|
|
392
|
+
side: 1
|
|
393
|
+
}).range(lineStart)
|
|
394
|
+
]);
|
|
395
|
+
view.update([]);
|
|
396
|
+
}, delay);
|
|
387
397
|
}
|
|
388
398
|
destroy() {
|
|
389
399
|
if (this._timeout) {
|
|
@@ -502,156 +512,234 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
502
512
|
};
|
|
503
513
|
|
|
504
514
|
// src/extensions/auto-scroll.ts
|
|
515
|
+
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
505
516
|
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
506
|
-
import { addEventListener, combine } from "@dxos/async";
|
|
517
|
+
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
507
518
|
import { Domino } from "@dxos/ui";
|
|
519
|
+
import { getSize } from "@dxos/ui-theme";
|
|
508
520
|
|
|
509
|
-
// src/extensions/
|
|
521
|
+
// src/extensions/scroller.ts
|
|
510
522
|
import { StateEffect } from "@codemirror/state";
|
|
511
523
|
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
512
|
-
|
|
513
|
-
var
|
|
514
|
-
|
|
524
|
+
import { log as log2 } from "@dxos/log";
|
|
525
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
|
|
526
|
+
var scrollerLineEffect = StateEffect.define();
|
|
527
|
+
var scrollerCrawlEffect = StateEffect.define();
|
|
528
|
+
var scrollToLine = (view, options) => {
|
|
529
|
+
view.dispatch({
|
|
530
|
+
effects: scrollerLineEffect.of(options)
|
|
531
|
+
});
|
|
532
|
+
};
|
|
533
|
+
var scroller = ({ overScroll = 0 } = {}) => {
|
|
534
|
+
const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
|
|
515
535
|
view;
|
|
536
|
+
crawler;
|
|
516
537
|
constructor(view) {
|
|
517
538
|
this.view = view;
|
|
539
|
+
this.crawler = createCrawler(this.view);
|
|
518
540
|
}
|
|
519
541
|
// No-op.
|
|
520
542
|
destroy() {
|
|
543
|
+
this.crawler.cancel();
|
|
521
544
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
const doc = this.view.state.doc;
|
|
529
|
-
const targetLine = Math.max(0, lineNumber - 1);
|
|
530
|
-
if (behavior === "instant") {
|
|
531
|
-
requestAnimationFrame(() => {
|
|
532
|
-
this.view.dispatch({
|
|
533
|
-
selection: {
|
|
534
|
-
anchor: doc.line(targetLine + 1).from
|
|
535
|
-
},
|
|
536
|
-
scrollIntoView: true
|
|
537
|
-
});
|
|
538
|
-
});
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
if (lineNumber === -1) {
|
|
542
|
-
this.animateScroll(scroller, scroller.scrollHeight - scroller.clientHeight);
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
if (targetLine >= doc.lines) {
|
|
546
|
-
const targetScrollTop2 = scroller.scrollHeight - scroller.clientHeight + (animOffset || 0);
|
|
547
|
-
this.animateScroll(scroller, targetScrollTop2);
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
const lineStart = doc.line(targetLine + 1).from;
|
|
551
|
-
const coords = this.view.coordsAtPos(lineStart);
|
|
552
|
-
if (!coords) {
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
const currentScrollTop = scroller.scrollTop;
|
|
556
|
-
const scrollerRect = scroller.getBoundingClientRect();
|
|
557
|
-
const maxScrollTop = scroller.scrollHeight - scroller.clientHeight;
|
|
558
|
-
let targetScrollTop;
|
|
559
|
-
if (animPosition === "end") {
|
|
560
|
-
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + animOffset;
|
|
545
|
+
cancel() {
|
|
546
|
+
this.crawler.cancel();
|
|
547
|
+
}
|
|
548
|
+
crawl(start = false) {
|
|
549
|
+
if (start) {
|
|
550
|
+
this.crawler.scroll();
|
|
561
551
|
} else {
|
|
562
|
-
|
|
552
|
+
this.crawler.cancel();
|
|
563
553
|
}
|
|
564
|
-
const clampedScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
565
|
-
this.animateScroll(scroller, clampedScrollTop);
|
|
566
554
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
555
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
556
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
557
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
558
|
+
const doc = this.view.state.doc;
|
|
559
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
560
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
561
|
+
const lineStart = doc.line(line + 1).from;
|
|
562
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
563
|
+
if (coords) {
|
|
564
|
+
const currentScrollTop = scrollTop;
|
|
565
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
566
|
+
if (position === "end") {
|
|
567
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
568
|
+
} else {
|
|
569
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
570
|
+
}
|
|
571
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
572
|
+
}
|
|
573
573
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
top: targetScrollTop
|
|
577
|
-
behavior: "smooth"
|
|
574
|
+
requestAnimationFrame(() => {
|
|
575
|
+
this.view.scrollDOM.scrollTo({
|
|
576
|
+
top: targetScrollTop
|
|
578
577
|
});
|
|
579
|
-
}
|
|
578
|
+
});
|
|
580
579
|
}
|
|
581
580
|
});
|
|
582
581
|
return [
|
|
583
582
|
scrollPlugin,
|
|
584
|
-
//
|
|
583
|
+
// Listen for effect.
|
|
585
584
|
EditorView4.updateListener.of((update2) => {
|
|
586
585
|
update2.transactions.forEach((transaction) => {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
});
|
|
586
|
+
try {
|
|
587
|
+
const plugin = update2.view.plugin(scrollPlugin);
|
|
588
|
+
if (plugin) {
|
|
589
|
+
for (const effect of transaction.effects) {
|
|
590
|
+
if (effect.is(scrollerCrawlEffect)) {
|
|
591
|
+
plugin.crawl(effect.value);
|
|
592
|
+
} else if (effect.is(scrollerLineEffect)) {
|
|
593
|
+
plugin.scroll(effect.value);
|
|
594
|
+
}
|
|
597
595
|
}
|
|
598
596
|
}
|
|
597
|
+
} catch (err) {
|
|
598
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
|
|
599
599
|
}
|
|
600
600
|
});
|
|
601
|
+
}),
|
|
602
|
+
// Styles.
|
|
603
|
+
EditorView4.theme({
|
|
604
|
+
".cm-scroller": {
|
|
605
|
+
overflowY: "scroll",
|
|
606
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
607
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
608
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
609
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
610
|
+
overflowAnchor: "auto"
|
|
611
|
+
},
|
|
612
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
613
|
+
display: "none"
|
|
614
|
+
},
|
|
615
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
616
|
+
background: "transparent",
|
|
617
|
+
transition: "background 0.15s"
|
|
618
|
+
},
|
|
619
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
620
|
+
background: "var(--color-scrollbar-thumb)"
|
|
621
|
+
},
|
|
622
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
623
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
624
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
625
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
626
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
627
|
+
".cm-content::after": {
|
|
628
|
+
content: '""',
|
|
629
|
+
display: "block",
|
|
630
|
+
height: `${overScroll}px`
|
|
631
|
+
},
|
|
632
|
+
".cm-scroll-button": {
|
|
633
|
+
position: "absolute",
|
|
634
|
+
bottom: "0.5rem",
|
|
635
|
+
right: "1rem"
|
|
636
|
+
}
|
|
601
637
|
})
|
|
602
638
|
];
|
|
603
639
|
};
|
|
604
|
-
|
|
605
|
-
view.
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
640
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
641
|
+
const el = view.scrollDOM;
|
|
642
|
+
let currentTop = 0;
|
|
643
|
+
let velocity = 0;
|
|
644
|
+
let rafId = null;
|
|
645
|
+
let lastTime = 0;
|
|
646
|
+
function frame(now) {
|
|
647
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
648
|
+
lastTime = now;
|
|
649
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
650
|
+
const delta = targetTop - currentTop;
|
|
651
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
652
|
+
el.scrollTop = targetTop;
|
|
653
|
+
currentTop = targetTop;
|
|
654
|
+
velocity = 0;
|
|
655
|
+
rafId = null;
|
|
656
|
+
lastTime = 0;
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
660
|
+
velocity += accel * dt;
|
|
661
|
+
currentTop += velocity * dt;
|
|
662
|
+
el.scrollTop = currentTop;
|
|
663
|
+
rafId = requestAnimationFrame(frame);
|
|
664
|
+
}
|
|
665
|
+
return {
|
|
666
|
+
scroll: () => {
|
|
667
|
+
if (rafId === null) {
|
|
668
|
+
currentTop = el.scrollTop;
|
|
669
|
+
lastTime = 0;
|
|
670
|
+
rafId = requestAnimationFrame(frame);
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
cancel: () => {
|
|
674
|
+
if (rafId !== null) {
|
|
675
|
+
cancelAnimationFrame(rafId);
|
|
676
|
+
velocity = 0;
|
|
677
|
+
lastTime = 0;
|
|
678
|
+
rafId = null;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
}
|
|
612
683
|
|
|
613
684
|
// src/extensions/auto-scroll.ts
|
|
614
|
-
var
|
|
685
|
+
var autoScrollEffect = StateEffect2.define();
|
|
686
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
615
687
|
let buttonContainer;
|
|
616
|
-
let isPinned =
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
view.dispatch({
|
|
624
|
-
effects: scrollToLineEffect.of({
|
|
625
|
-
line: -1,
|
|
626
|
-
options: {
|
|
627
|
-
position: "end",
|
|
628
|
-
behavior
|
|
629
|
-
}
|
|
630
|
-
})
|
|
631
|
-
});
|
|
688
|
+
let isPinned = true;
|
|
689
|
+
let jumpPending = false;
|
|
690
|
+
let enabled = true;
|
|
691
|
+
let firstUpdate = true;
|
|
692
|
+
const setPinned = (pinned) => {
|
|
693
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
694
|
+
isPinned = pinned;
|
|
632
695
|
};
|
|
633
|
-
const triggerUpdate = intervalUntilQuiet((view) => {
|
|
634
|
-
if (isPinned) {
|
|
635
|
-
scrollToBottom(view);
|
|
636
|
-
}
|
|
637
|
-
}, throttleDelay);
|
|
638
696
|
return [
|
|
639
|
-
// Update listener for
|
|
640
|
-
EditorView5.updateListener.of((
|
|
697
|
+
// Update listener for scrolling when content changes.
|
|
698
|
+
EditorView5.updateListener.of((update2) => {
|
|
699
|
+
const { view, heightChanged, state, startState } = update2;
|
|
700
|
+
for (const tr of update2.transactions) {
|
|
701
|
+
for (const effect of tr.effects) {
|
|
702
|
+
if (effect.is(autoScrollEffect)) {
|
|
703
|
+
enabled = effect.value;
|
|
704
|
+
if (enabled) {
|
|
705
|
+
setPinned(true);
|
|
706
|
+
view.dispatch({
|
|
707
|
+
effects: scrollerCrawlEffect.of(true)
|
|
708
|
+
});
|
|
709
|
+
} else {
|
|
710
|
+
view.dispatch({
|
|
711
|
+
effects: scrollerCrawlEffect.of(false)
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (!enabled) {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
721
|
+
firstUpdate = false;
|
|
722
|
+
jumpPending = true;
|
|
723
|
+
requestAnimationFrame(() => {
|
|
724
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
725
|
+
jumpPending = false;
|
|
726
|
+
});
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
firstUpdate = false;
|
|
730
|
+
if (jumpPending) {
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
641
733
|
if (heightChanged) {
|
|
642
734
|
if (isPinned) {
|
|
643
|
-
const
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
if (shouldScroll) {
|
|
652
|
-
triggerUpdate(view);
|
|
653
|
-
}
|
|
654
|
-
} else if (distanceFromBottom < 0) {
|
|
735
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
736
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
737
|
+
if (delta > 0) {
|
|
738
|
+
setPinned(true);
|
|
739
|
+
view.dispatch({
|
|
740
|
+
effects: scrollerCrawlEffect.of(true)
|
|
741
|
+
});
|
|
742
|
+
} else if (delta < -1) {
|
|
655
743
|
setPinned(false);
|
|
656
744
|
}
|
|
657
745
|
} else {
|
|
@@ -661,17 +749,63 @@ var autoScroll = ({ pinned = true, threshold = 100, throttleDelay = 500, onAutoS
|
|
|
661
749
|
}
|
|
662
750
|
}
|
|
663
751
|
}),
|
|
752
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
753
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
754
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
755
|
+
scrollOnResize ? ViewPlugin6.fromClass(class {
|
|
756
|
+
observer;
|
|
757
|
+
firstObservation = true;
|
|
758
|
+
destroyed = false;
|
|
759
|
+
constructor(view) {
|
|
760
|
+
const onResize = throttle(() => {
|
|
761
|
+
if (this.destroyed || !enabled) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
setPinned(true);
|
|
765
|
+
requestAnimationFrame(() => {
|
|
766
|
+
if (this.destroyed) {
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
view.scrollDOM.scrollTo({
|
|
770
|
+
top: view.scrollDOM.scrollHeight,
|
|
771
|
+
behavior: "instant"
|
|
772
|
+
});
|
|
773
|
+
view.dispatch({
|
|
774
|
+
effects: scrollerCrawlEffect.of(false)
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
}, 50);
|
|
778
|
+
this.observer = new ResizeObserver(() => {
|
|
779
|
+
if (this.firstObservation) {
|
|
780
|
+
this.firstObservation = false;
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
onResize();
|
|
784
|
+
});
|
|
785
|
+
this.observer.observe(view.scrollDOM);
|
|
786
|
+
}
|
|
787
|
+
destroy() {
|
|
788
|
+
this.destroyed = true;
|
|
789
|
+
this.observer.disconnect();
|
|
790
|
+
}
|
|
791
|
+
}) : [],
|
|
664
792
|
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
665
793
|
ViewPlugin6.fromClass(class {
|
|
666
794
|
cleanup;
|
|
667
795
|
constructor(view) {
|
|
668
|
-
this.cleanup = createUserScrollDetector(view.scrollDOM, () => {
|
|
796
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
|
|
669
797
|
requestAnimationFrame(() => {
|
|
670
798
|
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
671
|
-
const
|
|
672
|
-
|
|
799
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
800
|
+
const pinned = delta === 0;
|
|
801
|
+
setPinned(pinned);
|
|
802
|
+
if (!pinned) {
|
|
803
|
+
view.dispatch({
|
|
804
|
+
effects: scrollerCrawlEffect.of(false)
|
|
805
|
+
});
|
|
806
|
+
}
|
|
673
807
|
});
|
|
674
|
-
});
|
|
808
|
+
}, 500));
|
|
675
809
|
}
|
|
676
810
|
destroy() {
|
|
677
811
|
this.cleanup();
|
|
@@ -680,41 +814,24 @@ var autoScroll = ({ pinned = true, threshold = 100, throttleDelay = 500, onAutoS
|
|
|
680
814
|
// Scroll button.
|
|
681
815
|
ViewPlugin6.fromClass(class {
|
|
682
816
|
constructor(view) {
|
|
683
|
-
const icon = Domino.of("dx-icon").attributes({
|
|
817
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
684
818
|
icon: "ph--arrow-down--regular"
|
|
685
819
|
});
|
|
686
|
-
const button = Domino.of("button").classNames("dx-button bg-
|
|
820
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
687
821
|
"data-density": "fine"
|
|
688
|
-
}).
|
|
689
|
-
|
|
822
|
+
}).append(icon).on("click", () => {
|
|
823
|
+
setPinned(true);
|
|
824
|
+
view.dispatch({
|
|
825
|
+
effects: scrollerLineEffect.of({
|
|
826
|
+
line: -1,
|
|
827
|
+
position: "end",
|
|
828
|
+
behavior: "smooth"
|
|
829
|
+
})
|
|
830
|
+
});
|
|
690
831
|
});
|
|
691
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").
|
|
832
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
692
833
|
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
693
834
|
}
|
|
694
|
-
}),
|
|
695
|
-
// Styles.
|
|
696
|
-
EditorView5.theme({
|
|
697
|
-
".cm-content": {
|
|
698
|
-
paddingBottom: `${threshold}px`
|
|
699
|
-
},
|
|
700
|
-
".cm-scroller": {
|
|
701
|
-
paddingBottom: "0"
|
|
702
|
-
},
|
|
703
|
-
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
704
|
-
display: "none"
|
|
705
|
-
},
|
|
706
|
-
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
707
|
-
background: "transparent",
|
|
708
|
-
transition: "background 0.15s"
|
|
709
|
-
},
|
|
710
|
-
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
711
|
-
background: "var(--dx-scrollbarThumb)"
|
|
712
|
-
},
|
|
713
|
-
".cm-scroll-button": {
|
|
714
|
-
position: "absolute",
|
|
715
|
-
bottom: "0.5rem",
|
|
716
|
-
right: "1rem"
|
|
717
|
-
}
|
|
718
835
|
})
|
|
719
836
|
];
|
|
720
837
|
};
|
|
@@ -727,28 +844,6 @@ function createUserScrollDetector(element, onUserScroll) {
|
|
|
727
844
|
}
|
|
728
845
|
}));
|
|
729
846
|
}
|
|
730
|
-
function intervalUntilQuiet(fn, interval) {
|
|
731
|
-
let timer = null;
|
|
732
|
-
let quietTimer = null;
|
|
733
|
-
let latestArgs;
|
|
734
|
-
return (...args) => {
|
|
735
|
-
latestArgs = args;
|
|
736
|
-
if (quietTimer) {
|
|
737
|
-
clearTimeout(quietTimer);
|
|
738
|
-
}
|
|
739
|
-
quietTimer = setTimeout(() => {
|
|
740
|
-
if (timer) {
|
|
741
|
-
clearInterval(timer);
|
|
742
|
-
timer = null;
|
|
743
|
-
}
|
|
744
|
-
quietTimer = null;
|
|
745
|
-
}, interval);
|
|
746
|
-
if (!timer) {
|
|
747
|
-
fn(...latestArgs);
|
|
748
|
-
timer = setInterval(() => fn(...latestArgs), interval);
|
|
749
|
-
}
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
847
|
|
|
753
848
|
// src/extensions/automerge/automerge.ts
|
|
754
849
|
import { next as A3 } from "@automerge/automerge";
|
|
@@ -762,42 +857,32 @@ var initialSync = Transaction.userEvent.of("initial.sync");
|
|
|
762
857
|
|
|
763
858
|
// src/extensions/automerge/cursor.ts
|
|
764
859
|
import { fromCursor, toCursor } from "@dxos/echo-db";
|
|
765
|
-
import { log as
|
|
766
|
-
var
|
|
860
|
+
import { log as log3 } from "@dxos/log";
|
|
861
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
|
|
767
862
|
var cursorConverter = (accessor) => ({
|
|
768
863
|
toCursor: (pos, assoc) => {
|
|
769
864
|
try {
|
|
770
865
|
return toCursor(accessor, pos, assoc);
|
|
771
866
|
} catch (err) {
|
|
772
|
-
|
|
773
|
-
F: __dxlog_file2,
|
|
774
|
-
L: 15,
|
|
775
|
-
S: void 0,
|
|
776
|
-
C: (f, a) => f(...a)
|
|
777
|
-
});
|
|
867
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 11, S: void 0 });
|
|
778
868
|
return "";
|
|
779
869
|
}
|
|
780
870
|
},
|
|
781
|
-
fromCursor: (
|
|
871
|
+
fromCursor: (cursor) => {
|
|
782
872
|
try {
|
|
783
|
-
return fromCursor(accessor,
|
|
873
|
+
return fromCursor(accessor, cursor);
|
|
784
874
|
} catch (err) {
|
|
785
|
-
|
|
786
|
-
F: __dxlog_file2,
|
|
787
|
-
L: 24,
|
|
788
|
-
S: void 0,
|
|
789
|
-
C: (f, a) => f(...a)
|
|
790
|
-
});
|
|
875
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 19, S: void 0 });
|
|
791
876
|
return 0;
|
|
792
877
|
}
|
|
793
878
|
}
|
|
794
879
|
});
|
|
795
880
|
|
|
796
881
|
// src/extensions/automerge/defs.ts
|
|
797
|
-
import { Annotation, StateEffect as
|
|
882
|
+
import { Annotation, StateEffect as StateEffect3 } from "@codemirror/state";
|
|
798
883
|
var getPath = (state, field) => state.field(field).path;
|
|
799
884
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
800
|
-
var updateHeadsEffect =
|
|
885
|
+
var updateHeadsEffect = StateEffect3.define({});
|
|
801
886
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
802
887
|
newHeads
|
|
803
888
|
});
|
|
@@ -808,7 +893,7 @@ var isReconcile = (tr) => {
|
|
|
808
893
|
|
|
809
894
|
// src/extensions/automerge/sync.ts
|
|
810
895
|
import { next as A2 } from "@automerge/automerge";
|
|
811
|
-
import { log as
|
|
896
|
+
import { log as log4 } from "@dxos/log";
|
|
812
897
|
|
|
813
898
|
// src/extensions/automerge/update-automerge.ts
|
|
814
899
|
import { next as A } from "@automerge/automerge";
|
|
@@ -949,7 +1034,7 @@ var charPath = (textPath, candidatePath) => {
|
|
|
949
1034
|
};
|
|
950
1035
|
|
|
951
1036
|
// src/extensions/automerge/sync.ts
|
|
952
|
-
var
|
|
1037
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
|
|
953
1038
|
var Syncer = class {
|
|
954
1039
|
_handle;
|
|
955
1040
|
_state;
|
|
@@ -972,12 +1057,7 @@ var Syncer = class {
|
|
|
972
1057
|
this._pending = false;
|
|
973
1058
|
}
|
|
974
1059
|
onEditorChange(view) {
|
|
975
|
-
|
|
976
|
-
F: __dxlog_file3,
|
|
977
|
-
L: 45,
|
|
978
|
-
S: this,
|
|
979
|
-
C: (f, a) => f(...a)
|
|
980
|
-
});
|
|
1060
|
+
log4("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 35, S: this });
|
|
981
1061
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
982
1062
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
983
1063
|
if (newHeads) {
|
|
@@ -988,12 +1068,7 @@ var Syncer = class {
|
|
|
988
1068
|
}
|
|
989
1069
|
}
|
|
990
1070
|
onAutomergeChange(view) {
|
|
991
|
-
|
|
992
|
-
F: __dxlog_file3,
|
|
993
|
-
L: 60,
|
|
994
|
-
S: this,
|
|
995
|
-
C: (f, a) => f(...a)
|
|
996
|
-
});
|
|
1071
|
+
log4("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 47, S: this });
|
|
997
1072
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
998
1073
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
999
1074
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1055,6 +1130,17 @@ var automerge = (accessor) => {
|
|
|
1055
1130
|
const value = DocAccessor.getValue(accessor);
|
|
1056
1131
|
const current = this._view.state.doc.toString();
|
|
1057
1132
|
if (value !== current) {
|
|
1133
|
+
this._view.dispatch({
|
|
1134
|
+
changes: {
|
|
1135
|
+
from: 0,
|
|
1136
|
+
to: this._view.state.doc.length,
|
|
1137
|
+
insert: value
|
|
1138
|
+
},
|
|
1139
|
+
annotations: [
|
|
1140
|
+
initialSync,
|
|
1141
|
+
reconcileAnnotation.of(true)
|
|
1142
|
+
]
|
|
1143
|
+
});
|
|
1058
1144
|
}
|
|
1059
1145
|
});
|
|
1060
1146
|
}
|
|
@@ -1082,7 +1168,7 @@ import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
|
1082
1168
|
import { Decoration as Decoration5, EditorView as EditorView7, ViewPlugin as ViewPlugin8, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1083
1169
|
import { Event } from "@dxos/async";
|
|
1084
1170
|
import { Context } from "@dxos/context";
|
|
1085
|
-
var
|
|
1171
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
1086
1172
|
var dummyProvider = {
|
|
1087
1173
|
remoteStateChange: new Event(),
|
|
1088
1174
|
open: () => {
|
|
@@ -1105,10 +1191,7 @@ var awareness = (provider = dummyProvider) => {
|
|
|
1105
1191
|
];
|
|
1106
1192
|
};
|
|
1107
1193
|
var RemoteSelectionsDecorator = class {
|
|
1108
|
-
_ctx = new Context(void 0, {
|
|
1109
|
-
F: __dxlog_file4,
|
|
1110
|
-
L: 80
|
|
1111
|
-
});
|
|
1194
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
|
|
1112
1195
|
_cursorConverter;
|
|
1113
1196
|
_provider;
|
|
1114
1197
|
_lastAnchor;
|
|
@@ -1319,8 +1402,8 @@ var styles = EditorView7.theme({
|
|
|
1319
1402
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
1320
1403
|
import { Context as Context2 } from "@dxos/context";
|
|
1321
1404
|
import { invariant } from "@dxos/invariant";
|
|
1322
|
-
import { log as
|
|
1323
|
-
var
|
|
1405
|
+
import { log as log5 } from "@dxos/log";
|
|
1406
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
|
|
1324
1407
|
var DEBOUNCE_INTERVAL = 100;
|
|
1325
1408
|
var SpaceAwarenessProvider = class {
|
|
1326
1409
|
_remoteStates = /* @__PURE__ */ new Map();
|
|
@@ -1339,10 +1422,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1339
1422
|
this._info = info;
|
|
1340
1423
|
}
|
|
1341
1424
|
open() {
|
|
1342
|
-
this._ctx = new Context2(void 0, {
|
|
1343
|
-
F: __dxlog_file5,
|
|
1344
|
-
L: 57
|
|
1345
|
-
});
|
|
1425
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
|
|
1346
1426
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1347
1427
|
if (this._localState) {
|
|
1348
1428
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1367,14 +1447,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1367
1447
|
void this._messenger.postMessage(this._channel, {
|
|
1368
1448
|
kind: "query"
|
|
1369
1449
|
}).catch((err) => {
|
|
1370
|
-
|
|
1450
|
+
log5.debug("failed to query awareness", {
|
|
1371
1451
|
err
|
|
1372
|
-
}, {
|
|
1373
|
-
F: __dxlog_file5,
|
|
1374
|
-
L: 91,
|
|
1375
|
-
S: this,
|
|
1376
|
-
C: (f, a) => f(...a)
|
|
1377
|
-
});
|
|
1452
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
|
|
1378
1453
|
});
|
|
1379
1454
|
}
|
|
1380
1455
|
close() {
|
|
@@ -1386,15 +1461,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1386
1461
|
return Array.from(this._remoteStates.values());
|
|
1387
1462
|
}
|
|
1388
1463
|
update(position) {
|
|
1389
|
-
invariant(this._postTask, void 0, {
|
|
1390
|
-
F: __dxlog_file5,
|
|
1391
|
-
L: 106,
|
|
1392
|
-
S: this,
|
|
1393
|
-
A: [
|
|
1394
|
-
"this._postTask",
|
|
1395
|
-
""
|
|
1396
|
-
]
|
|
1397
|
-
});
|
|
1464
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1398
1465
|
this._localState = {
|
|
1399
1466
|
peerId: this._peerId,
|
|
1400
1467
|
position,
|
|
@@ -1403,27 +1470,11 @@ var SpaceAwarenessProvider = class {
|
|
|
1403
1470
|
this._postTask.schedule();
|
|
1404
1471
|
}
|
|
1405
1472
|
_handleQueryMessage() {
|
|
1406
|
-
invariant(this._postTask, void 0, {
|
|
1407
|
-
F: __dxlog_file5,
|
|
1408
|
-
L: 117,
|
|
1409
|
-
S: this,
|
|
1410
|
-
A: [
|
|
1411
|
-
"this._postTask",
|
|
1412
|
-
""
|
|
1413
|
-
]
|
|
1414
|
-
});
|
|
1473
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1415
1474
|
this._postTask.schedule();
|
|
1416
1475
|
}
|
|
1417
1476
|
_handlePostMessage(message) {
|
|
1418
|
-
invariant(message.kind === "post", void 0, {
|
|
1419
|
-
F: __dxlog_file5,
|
|
1420
|
-
L: 122,
|
|
1421
|
-
S: this,
|
|
1422
|
-
A: [
|
|
1423
|
-
"message.kind === 'post'",
|
|
1424
|
-
""
|
|
1425
|
-
]
|
|
1426
|
-
});
|
|
1477
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1427
1478
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1428
1479
|
this.remoteStateChange.emit();
|
|
1429
1480
|
}
|
|
@@ -1432,9 +1483,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1432
1483
|
// src/extensions/blast.ts
|
|
1433
1484
|
import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
|
|
1434
1485
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1435
|
-
import { throttle } from "@dxos/async";
|
|
1486
|
+
import { throttle as throttle2 } from "@dxos/async";
|
|
1436
1487
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1437
|
-
var
|
|
1488
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
|
|
1438
1489
|
var defaultOptions = {
|
|
1439
1490
|
effect: 2,
|
|
1440
1491
|
maxParticles: 200,
|
|
@@ -1552,15 +1603,7 @@ var Blaster = class {
|
|
|
1552
1603
|
return this._node;
|
|
1553
1604
|
}
|
|
1554
1605
|
initialize() {
|
|
1555
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1556
|
-
F: __dxlog_file6,
|
|
1557
|
-
L: 142,
|
|
1558
|
-
S: this,
|
|
1559
|
-
A: [
|
|
1560
|
-
"!this._canvas && !this._ctx",
|
|
1561
|
-
""
|
|
1562
|
-
]
|
|
1563
|
-
});
|
|
1606
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1564
1607
|
this._canvas = document.createElement("canvas");
|
|
1565
1608
|
this._canvas.id = "code-blast-canvas";
|
|
1566
1609
|
this._canvas.style.position = "absolute";
|
|
@@ -1589,15 +1632,7 @@ var Blaster = class {
|
|
|
1589
1632
|
}
|
|
1590
1633
|
}
|
|
1591
1634
|
start() {
|
|
1592
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1593
|
-
F: __dxlog_file6,
|
|
1594
|
-
L: 181,
|
|
1595
|
-
S: this,
|
|
1596
|
-
A: [
|
|
1597
|
-
"this._canvas && this._ctx",
|
|
1598
|
-
""
|
|
1599
|
-
]
|
|
1600
|
-
});
|
|
1635
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1601
1636
|
this._running = true;
|
|
1602
1637
|
this.loop();
|
|
1603
1638
|
}
|
|
@@ -1624,11 +1659,11 @@ var Blaster = class {
|
|
|
1624
1659
|
this.drawParticles();
|
|
1625
1660
|
requestAnimationFrame(this.loop.bind(this));
|
|
1626
1661
|
}
|
|
1627
|
-
shake =
|
|
1662
|
+
shake = throttle2(({ time }) => {
|
|
1628
1663
|
this._shakeTime = this._shakeTimeMax || time;
|
|
1629
1664
|
this._shakeTimeMax = time;
|
|
1630
1665
|
}, 100);
|
|
1631
|
-
spawn =
|
|
1666
|
+
spawn = throttle2(({ element, point }) => {
|
|
1632
1667
|
const color = getRGBComponents(element, this._options.color);
|
|
1633
1668
|
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
1634
1669
|
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
@@ -1802,11 +1837,11 @@ var blocks = () => [
|
|
|
1802
1837
|
".cm-line.block-line": {
|
|
1803
1838
|
paddingLeft: "0.75rem",
|
|
1804
1839
|
paddingRight: "0.75rem",
|
|
1805
|
-
borderLeft: "1px solid var(--
|
|
1806
|
-
borderRight: "1px solid var(--
|
|
1840
|
+
borderLeft: "1px solid var(--color-subdued-separator)",
|
|
1841
|
+
borderRight: "1px solid var(--color-subdued-separator)"
|
|
1807
1842
|
},
|
|
1808
1843
|
".cm-line.block-single": {
|
|
1809
|
-
border: "1px solid var(--
|
|
1844
|
+
border: "1px solid var(--color-subdued-separator)",
|
|
1810
1845
|
borderRadius: "6px",
|
|
1811
1846
|
paddingTop: "0.5rem",
|
|
1812
1847
|
paddingBottom: "0.5rem",
|
|
@@ -1814,7 +1849,7 @@ var blocks = () => [
|
|
|
1814
1849
|
marginBottom: "0.5rem"
|
|
1815
1850
|
},
|
|
1816
1851
|
".cm-line.block-first": {
|
|
1817
|
-
borderTop: "1px solid var(--
|
|
1852
|
+
borderTop: "1px solid var(--color-subdued-separator)",
|
|
1818
1853
|
borderTopLeftRadius: "6px",
|
|
1819
1854
|
borderTopRightRadius: "6px",
|
|
1820
1855
|
paddingTop: "0.5rem",
|
|
@@ -1822,7 +1857,7 @@ var blocks = () => [
|
|
|
1822
1857
|
},
|
|
1823
1858
|
".cm-line.block-middle": {},
|
|
1824
1859
|
".cm-line.block-last": {
|
|
1825
|
-
borderBottom: "1px solid var(--
|
|
1860
|
+
borderBottom: "1px solid var(--color-subdued-separator)",
|
|
1826
1861
|
borderBottomLeftRadius: "6px",
|
|
1827
1862
|
borderBottomRightRadius: "6px",
|
|
1828
1863
|
paddingBottom: "0.5rem",
|
|
@@ -1832,13 +1867,13 @@ var blocks = () => [
|
|
|
1832
1867
|
];
|
|
1833
1868
|
|
|
1834
1869
|
// src/extensions/bookmarks.ts
|
|
1835
|
-
import { Prec as Prec3, StateEffect as
|
|
1870
|
+
import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
|
|
1836
1871
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1837
|
-
import { log as
|
|
1838
|
-
var
|
|
1839
|
-
var addBookmark =
|
|
1840
|
-
var removeBookmark =
|
|
1841
|
-
var clearBookmarks =
|
|
1872
|
+
import { log as log6 } from "@dxos/log";
|
|
1873
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1874
|
+
var addBookmark = StateEffect4.define();
|
|
1875
|
+
var removeBookmark = StateEffect4.define();
|
|
1876
|
+
var clearBookmarks = StateEffect4.define();
|
|
1842
1877
|
var bookmarks = () => {
|
|
1843
1878
|
return [
|
|
1844
1879
|
bookmarksField,
|
|
@@ -1847,12 +1882,7 @@ var bookmarks = () => {
|
|
|
1847
1882
|
key: "Mod-ArrowUp",
|
|
1848
1883
|
run: (view) => {
|
|
1849
1884
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1850
|
-
|
|
1851
|
-
F: __dxlog_file7,
|
|
1852
|
-
L: 29,
|
|
1853
|
-
S: void 0,
|
|
1854
|
-
C: (f, a) => f(...a)
|
|
1855
|
-
});
|
|
1885
|
+
log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
|
|
1856
1886
|
return true;
|
|
1857
1887
|
}
|
|
1858
1888
|
},
|
|
@@ -1860,12 +1890,7 @@ var bookmarks = () => {
|
|
|
1860
1890
|
key: "Mod-ArrowDown",
|
|
1861
1891
|
run: (view) => {
|
|
1862
1892
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1863
|
-
|
|
1864
|
-
F: __dxlog_file7,
|
|
1865
|
-
L: 37,
|
|
1866
|
-
S: void 0,
|
|
1867
|
-
C: (f, a) => f(...a)
|
|
1868
|
-
});
|
|
1893
|
+
log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
|
|
1869
1894
|
return true;
|
|
1870
1895
|
}
|
|
1871
1896
|
}
|
|
@@ -1902,11 +1927,11 @@ var bookmarksField = StateField2.define({
|
|
|
1902
1927
|
|
|
1903
1928
|
// src/extensions/comments.ts
|
|
1904
1929
|
import { invertedEffects } from "@codemirror/commands";
|
|
1905
|
-
import { StateEffect as
|
|
1930
|
+
import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
|
|
1906
1931
|
import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1907
1932
|
import sortBy from "lodash.sortby";
|
|
1908
1933
|
import { debounce as debounce2 } from "@dxos/async";
|
|
1909
|
-
import { log as
|
|
1934
|
+
import { log as log7 } from "@dxos/log";
|
|
1910
1935
|
import { isNonNullable } from "@dxos/util";
|
|
1911
1936
|
|
|
1912
1937
|
// src/extensions/selection.ts
|
|
@@ -1915,9 +1940,9 @@ import { EditorView as EditorView10, keymap as keymap5 } from "@codemirror/view"
|
|
|
1915
1940
|
import { debounce } from "@dxos/async";
|
|
1916
1941
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1917
1942
|
import { isTruthy } from "@dxos/util";
|
|
1918
|
-
var
|
|
1943
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1919
1944
|
var documentId = singleValueFacet();
|
|
1920
|
-
var stateRestoreAnnotation = "dxos.
|
|
1945
|
+
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1921
1946
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1922
1947
|
return {
|
|
1923
1948
|
selection,
|
|
@@ -1930,28 +1955,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1930
1955
|
};
|
|
1931
1956
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1932
1957
|
getState: (id) => {
|
|
1933
|
-
invariant3(id, void 0, {
|
|
1934
|
-
F: __dxlog_file8,
|
|
1935
|
-
L: 47,
|
|
1936
|
-
S: void 0,
|
|
1937
|
-
A: [
|
|
1938
|
-
"id",
|
|
1939
|
-
""
|
|
1940
|
-
]
|
|
1941
|
-
});
|
|
1958
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
|
|
1942
1959
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1943
1960
|
return state ? JSON.parse(state) : void 0;
|
|
1944
1961
|
},
|
|
1945
1962
|
setState: (id, state) => {
|
|
1946
|
-
invariant3(id, void 0, {
|
|
1947
|
-
F: __dxlog_file8,
|
|
1948
|
-
L: 53,
|
|
1949
|
-
S: void 0,
|
|
1950
|
-
A: [
|
|
1951
|
-
"id",
|
|
1952
|
-
""
|
|
1953
|
-
]
|
|
1954
|
-
});
|
|
1963
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
|
|
1955
1964
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1956
1965
|
}
|
|
1957
1966
|
});
|
|
@@ -2003,10 +2012,10 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2003
2012
|
};
|
|
2004
2013
|
|
|
2005
2014
|
// src/extensions/comments.ts
|
|
2006
|
-
var
|
|
2007
|
-
var setComments =
|
|
2008
|
-
var setSelection =
|
|
2009
|
-
var setCommentState =
|
|
2015
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
2016
|
+
var setComments = StateEffect5.define();
|
|
2017
|
+
var setSelection = StateEffect5.define();
|
|
2018
|
+
var setCommentState = StateEffect5.define();
|
|
2010
2019
|
var commentsState = StateField3.define({
|
|
2011
2020
|
create: (state) => ({
|
|
2012
2021
|
id: state.facet(documentId),
|
|
@@ -2048,14 +2057,14 @@ var commentsState = StateField3.define({
|
|
|
2048
2057
|
var styles2 = EditorView11.theme({
|
|
2049
2058
|
".cm-comment, .cm-comment-current": {
|
|
2050
2059
|
padding: "3px 0",
|
|
2051
|
-
color: "var(--
|
|
2052
|
-
backgroundColor: "var(--
|
|
2060
|
+
color: "var(--color-cm-comment-text)",
|
|
2061
|
+
backgroundColor: "var(--color-cm-comment-surface)"
|
|
2053
2062
|
},
|
|
2054
2063
|
".cm-comment > span, .cm-comment-current > span": {
|
|
2055
2064
|
boxDecorationBreak: "clone",
|
|
2056
|
-
boxShadow: "0 0 1px 3px var(--
|
|
2057
|
-
backgroundColor: "var(--
|
|
2058
|
-
color: "var(--
|
|
2065
|
+
boxShadow: "0 0 1px 3px var(--color-cm-comment-surface)",
|
|
2066
|
+
backgroundColor: "var(--color-cm-comment-surface)",
|
|
2067
|
+
color: "var(--color-cm-comment-text)",
|
|
2059
2068
|
cursor: "pointer"
|
|
2060
2069
|
}
|
|
2061
2070
|
});
|
|
@@ -2073,12 +2082,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2073
2082
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2074
2083
|
const range = comment.range;
|
|
2075
2084
|
if (!range) {
|
|
2076
|
-
|
|
2077
|
-
F: __dxlog_file9,
|
|
2078
|
-
L: 140,
|
|
2079
|
-
S: void 0,
|
|
2080
|
-
C: (f, a) => f(...a)
|
|
2081
|
-
});
|
|
2085
|
+
log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
|
|
2082
2086
|
return void 0;
|
|
2083
2087
|
} else if (range.from === range.to) {
|
|
2084
2088
|
return void 0;
|
|
@@ -2088,7 +2092,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2088
2092
|
}).filter(isNonNullable);
|
|
2089
2093
|
return Decoration7.set(decorations2);
|
|
2090
2094
|
});
|
|
2091
|
-
var commentClickedEffect =
|
|
2095
|
+
var commentClickedEffect = StateEffect5.define();
|
|
2092
2096
|
var handleCommentClick = EditorView11.domEventHandlers({
|
|
2093
2097
|
click: (event, view) => {
|
|
2094
2098
|
let target = event.target;
|
|
@@ -2191,10 +2195,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2191
2195
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2192
2196
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2193
2197
|
if (!exists) {
|
|
2194
|
-
const
|
|
2198
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2195
2199
|
onUpdate({
|
|
2196
2200
|
id: comment.id,
|
|
2197
|
-
cursor
|
|
2201
|
+
cursor
|
|
2198
2202
|
});
|
|
2199
2203
|
}
|
|
2200
2204
|
}
|
|
@@ -2206,7 +2210,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2206
2210
|
from: changes.mapPos(comment.from, 1),
|
|
2207
2211
|
to: changes.mapPos(comment.to, 1)
|
|
2208
2212
|
});
|
|
2209
|
-
var restoreCommentEffect =
|
|
2213
|
+
var restoreCommentEffect = StateEffect5.define({
|
|
2210
2214
|
map: mapTrackedComment
|
|
2211
2215
|
});
|
|
2212
2216
|
var createComment = (view) => {
|
|
@@ -2223,13 +2227,13 @@ var createComment = (view) => {
|
|
|
2223
2227
|
}
|
|
2224
2228
|
});
|
|
2225
2229
|
}
|
|
2226
|
-
const
|
|
2230
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2227
2231
|
from,
|
|
2228
2232
|
to
|
|
2229
2233
|
});
|
|
2230
|
-
if (
|
|
2234
|
+
if (cursor) {
|
|
2231
2235
|
options.onCreate?.({
|
|
2232
|
-
cursor
|
|
2236
|
+
cursor,
|
|
2233
2237
|
from,
|
|
2234
2238
|
location: view.coordsAtPos(from)
|
|
2235
2239
|
});
|
|
@@ -2418,9 +2422,9 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin10.fro
|
|
|
2418
2422
|
// src/extensions/debug.ts
|
|
2419
2423
|
import { syntaxTree } from "@codemirror/language";
|
|
2420
2424
|
import { StateField as StateField4 } from "@codemirror/state";
|
|
2421
|
-
var debugNodeLogger = (
|
|
2425
|
+
var debugNodeLogger = (log12 = console.log) => {
|
|
2422
2426
|
const logTokens = (state) => syntaxTree(state).iterate({
|
|
2423
|
-
enter: (node) =>
|
|
2427
|
+
enter: (node) => log12(node.type)
|
|
2424
2428
|
});
|
|
2425
2429
|
return StateField4.define({
|
|
2426
2430
|
create: (state) => logTokens(state),
|
|
@@ -2455,8 +2459,8 @@ var dropFile = (options = {}) => {
|
|
|
2455
2459
|
};
|
|
2456
2460
|
var styles3 = EditorView12.theme({
|
|
2457
2461
|
".cm-dropCursor": {
|
|
2458
|
-
borderLeft: "2px solid var(--
|
|
2459
|
-
color: "var(--
|
|
2462
|
+
borderLeft: "2px solid var(--color-accent-text)",
|
|
2463
|
+
color: "var(--color-accent-text)",
|
|
2460
2464
|
padding: "0 4px"
|
|
2461
2465
|
},
|
|
2462
2466
|
".cm-dropCursor:after": {
|
|
@@ -2470,46 +2474,62 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2470
2474
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2471
2475
|
import { searchKeymap } from "@codemirror/search";
|
|
2472
2476
|
import { EditorState } from "@codemirror/state";
|
|
2473
|
-
import { EditorView as
|
|
2477
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2474
2478
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2475
2479
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2476
2480
|
import { generateName } from "@dxos/display-name";
|
|
2477
|
-
import { log as
|
|
2481
|
+
import { log as log8 } from "@dxos/log";
|
|
2478
2482
|
import { hexToHue, isTruthy as isTruthy2 } from "@dxos/util";
|
|
2479
2483
|
|
|
2480
|
-
// src/styles/
|
|
2484
|
+
// src/styles/theme.ts
|
|
2485
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
2481
2486
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2482
2487
|
var headings = {
|
|
2483
|
-
1:
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2488
|
+
1: {
|
|
2489
|
+
className: "text-3xl",
|
|
2490
|
+
fontSize: "var(--text-3xl)",
|
|
2491
|
+
lineHeight: "var(--text-4xl--line-height)"
|
|
2492
|
+
},
|
|
2493
|
+
2: {
|
|
2494
|
+
className: "text-2xl",
|
|
2495
|
+
fontSize: "var(--text-2xl)",
|
|
2496
|
+
lineHeight: "var(--text-3xl--line-height)"
|
|
2497
|
+
},
|
|
2498
|
+
3: {
|
|
2499
|
+
className: "text-xl",
|
|
2500
|
+
fontSize: "var(--text-xl)",
|
|
2501
|
+
lineHeight: "var(--text-2xl--line-height)"
|
|
2502
|
+
},
|
|
2503
|
+
4: {
|
|
2504
|
+
className: "text-lg",
|
|
2505
|
+
fontSize: "var(--text-lg)",
|
|
2506
|
+
lineHeight: "var(--text-xl--line-height)"
|
|
2507
|
+
},
|
|
2508
|
+
5: {
|
|
2509
|
+
className: "text-base",
|
|
2510
|
+
fontSize: "var(--text-base)",
|
|
2511
|
+
lineHeight: "var(--text-lg--line-height)"
|
|
2512
|
+
},
|
|
2513
|
+
6: {
|
|
2514
|
+
className: "text-base",
|
|
2515
|
+
fontSize: "var(--text-base)",
|
|
2516
|
+
lineHeight: "var(--text-base--line-height)"
|
|
2517
|
+
}
|
|
2489
2518
|
};
|
|
2519
|
+
var fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
|
|
2520
|
+
var fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
|
|
2490
2521
|
var markdownTheme = {
|
|
2491
|
-
code: "font-mono
|
|
2492
|
-
codeMark: "font-mono
|
|
2493
|
-
mark: "
|
|
2494
|
-
heading: (level) => {
|
|
2495
|
-
|
|
2496
|
-
|
|
2522
|
+
code: "font-mono! cm-code-inline",
|
|
2523
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2524
|
+
mark: "font-mono!",
|
|
2525
|
+
heading: (level) => ({
|
|
2526
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2527
|
+
color: "var(--color-cm-heading) !important",
|
|
2528
|
+
lineHeight: headings[level].lineHeight,
|
|
2529
|
+
fontSize: headings[level].fontSize,
|
|
2530
|
+
fontWeight: "100 !important"
|
|
2531
|
+
})
|
|
2497
2532
|
};
|
|
2498
|
-
|
|
2499
|
-
// src/styles/theme.ts
|
|
2500
|
-
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
2501
|
-
|
|
2502
|
-
// src/styles/tokens.ts
|
|
2503
|
-
import { tokens } from "@dxos/ui-theme";
|
|
2504
|
-
import { get } from "@dxos/util";
|
|
2505
|
-
var getToken = (path, defaultValue) => {
|
|
2506
|
-
const value = get(tokens, path, defaultValue);
|
|
2507
|
-
return value?.toString() ?? "";
|
|
2508
|
-
};
|
|
2509
|
-
var fontBody = getToken("fontFamily.body");
|
|
2510
|
-
var fontMono = getToken("fontFamily.mono");
|
|
2511
|
-
|
|
2512
|
-
// src/styles/theme.ts
|
|
2513
2533
|
var baseTheme = EditorView13.baseTheme({
|
|
2514
2534
|
/**
|
|
2515
2535
|
* Outer frame.
|
|
@@ -2521,17 +2541,28 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2521
2541
|
/**
|
|
2522
2542
|
* Scroller
|
|
2523
2543
|
*/
|
|
2524
|
-
".cm-scroller": {
|
|
2544
|
+
".cm-scroller": {
|
|
2545
|
+
// Browser scroll-anchoring: see comment in `scroller.ts`. `auto` lets the browser pin a
|
|
2546
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2547
|
+
// open/close) don't jump the user's view.
|
|
2548
|
+
overflowAnchor: "auto"
|
|
2549
|
+
},
|
|
2525
2550
|
".cm-scroller::-webkit-scrollbar": {
|
|
2526
|
-
width: "8px"
|
|
2551
|
+
width: "var(--scrollbar-size,8px)",
|
|
2552
|
+
height: "var(--scrollbar-size,8px)"
|
|
2553
|
+
},
|
|
2554
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2555
|
+
background: "transparent"
|
|
2556
|
+
},
|
|
2557
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2558
|
+
background: "transparent"
|
|
2527
2559
|
},
|
|
2528
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2529
2560
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2530
2561
|
background: "transparent",
|
|
2531
2562
|
transition: "background 0.15s"
|
|
2532
2563
|
},
|
|
2533
2564
|
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2534
|
-
background: "var(--
|
|
2565
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2535
2566
|
},
|
|
2536
2567
|
/**
|
|
2537
2568
|
* Content
|
|
@@ -2539,7 +2570,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2539
2570
|
*/
|
|
2540
2571
|
".cm-content": {
|
|
2541
2572
|
padding: "unset",
|
|
2542
|
-
lineHeight: "24px",
|
|
2543
2573
|
color: "unset"
|
|
2544
2574
|
},
|
|
2545
2575
|
/**
|
|
@@ -2553,8 +2583,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2553
2583
|
".cm-gutter": {},
|
|
2554
2584
|
".cm-gutter.cm-lineNumbers": {
|
|
2555
2585
|
paddingRight: "4px",
|
|
2556
|
-
borderRight: "1px solid var(--
|
|
2557
|
-
color: "var(--
|
|
2586
|
+
borderRight: "1px solid var(--color-subdued-separator)",
|
|
2587
|
+
color: "var(--color-subdued)"
|
|
2558
2588
|
},
|
|
2559
2589
|
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
|
2560
2590
|
minWidth: "40px"
|
|
@@ -2570,29 +2600,36 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2570
2600
|
* Line.
|
|
2571
2601
|
*/
|
|
2572
2602
|
".cm-line": {
|
|
2573
|
-
lineHeight:
|
|
2603
|
+
lineHeight: 1.5,
|
|
2574
2604
|
paddingInline: 0
|
|
2575
2605
|
},
|
|
2606
|
+
/**
|
|
2607
|
+
* Force all inline children to inherit line-height to prevent monospace font metrics
|
|
2608
|
+
* (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
|
|
2609
|
+
*/
|
|
2610
|
+
".cm-line *": {
|
|
2611
|
+
lineHeight: "inherit"
|
|
2612
|
+
},
|
|
2576
2613
|
".cm-activeLine": {
|
|
2577
|
-
background: "var(--
|
|
2614
|
+
background: "var(--color-cm-active-line)"
|
|
2578
2615
|
},
|
|
2579
2616
|
/**
|
|
2580
2617
|
* Cursor (layer).
|
|
2581
2618
|
*/
|
|
2582
2619
|
".cm-cursor, .cm-dropCursor": {
|
|
2583
|
-
borderLeft: "2px solid var(--
|
|
2620
|
+
borderLeft: "2px solid var(--color-cm-cursor)"
|
|
2584
2621
|
},
|
|
2585
2622
|
".cm-placeholder": {
|
|
2586
|
-
color: "var(--
|
|
2623
|
+
color: "var(--color-placeholder)"
|
|
2587
2624
|
},
|
|
2588
2625
|
/**
|
|
2589
2626
|
* Selection (layer).
|
|
2590
2627
|
*/
|
|
2591
2628
|
".cm-selectionBackground": {
|
|
2592
|
-
background: "var(--
|
|
2629
|
+
background: "var(--color-cm-selection)"
|
|
2593
2630
|
},
|
|
2594
2631
|
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
2595
|
-
background: "var(--
|
|
2632
|
+
background: "var(--color-cm-focused-selection)"
|
|
2596
2633
|
},
|
|
2597
2634
|
/**
|
|
2598
2635
|
* Search.
|
|
@@ -2602,8 +2639,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2602
2639
|
margin: "0 -3px",
|
|
2603
2640
|
padding: "3px",
|
|
2604
2641
|
borderRadius: "3px",
|
|
2605
|
-
background: "var(--
|
|
2606
|
-
color: "var(--
|
|
2642
|
+
background: "var(--color-cm-highlight-surface)",
|
|
2643
|
+
color: "var(--color-cm-highlight)"
|
|
2607
2644
|
},
|
|
2608
2645
|
".cm-searchMatch-selected": {
|
|
2609
2646
|
textDecoration: "underline"
|
|
@@ -2614,20 +2651,29 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2614
2651
|
".cm-link": {
|
|
2615
2652
|
textDecorationLine: "underline",
|
|
2616
2653
|
textDecorationThickness: "1px",
|
|
2617
|
-
textDecorationColor: "var(--
|
|
2654
|
+
textDecorationColor: "var(--color-separator)",
|
|
2618
2655
|
textUnderlineOffset: "2px",
|
|
2619
2656
|
borderRadius: ".125rem"
|
|
2620
2657
|
},
|
|
2621
2658
|
".cm-link > span": {
|
|
2622
|
-
color: "var(--
|
|
2659
|
+
color: "var(--color-accent-text)"
|
|
2660
|
+
},
|
|
2661
|
+
".cm-link > span:hover": {
|
|
2662
|
+
color: "var(--color-accent-text-hover)"
|
|
2623
2663
|
},
|
|
2624
2664
|
/**
|
|
2625
2665
|
* Tooltip.
|
|
2626
2666
|
*/
|
|
2627
2667
|
".cm-tooltip": {
|
|
2628
|
-
background: "var(--
|
|
2668
|
+
background: "var(--color-modal-surface)"
|
|
2629
2669
|
},
|
|
2630
2670
|
".cm-tooltip-below": {},
|
|
2671
|
+
".cm-tooltip-hover": {
|
|
2672
|
+
background: "var(--color-modal-surface)",
|
|
2673
|
+
border: "1px solid var(--color-separator)",
|
|
2674
|
+
borderRadius: "4px",
|
|
2675
|
+
overflow: "hidden"
|
|
2676
|
+
},
|
|
2631
2677
|
/**
|
|
2632
2678
|
* Autocomplete.
|
|
2633
2679
|
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
@@ -2635,7 +2681,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2635
2681
|
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
2636
2682
|
marginTop: "6px",
|
|
2637
2683
|
marginLeft: "-10px",
|
|
2638
|
-
border: "2px solid var(--
|
|
2684
|
+
border: "2px solid var(--color-separator)",
|
|
2639
2685
|
borderRadius: "4px"
|
|
2640
2686
|
},
|
|
2641
2687
|
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
@@ -2645,12 +2691,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2645
2691
|
padding: "4px"
|
|
2646
2692
|
},
|
|
2647
2693
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2648
|
-
background: "var(--
|
|
2649
|
-
color: "var(--
|
|
2694
|
+
background: "var(--color-active-surface)",
|
|
2695
|
+
color: "var(--color-base-surface-text)"
|
|
2650
2696
|
},
|
|
2651
2697
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2652
2698
|
paddingLeft: "4px !important",
|
|
2653
|
-
color: "var(--
|
|
2699
|
+
color: "var(--color-base-surface-text)"
|
|
2654
2700
|
},
|
|
2655
2701
|
/**
|
|
2656
2702
|
* Completion info.
|
|
@@ -2659,17 +2705,17 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2659
2705
|
width: "360px !important",
|
|
2660
2706
|
margin: "-10px 1px 0 1px",
|
|
2661
2707
|
padding: "8px !important",
|
|
2662
|
-
borderColor: "var(--
|
|
2708
|
+
borderColor: "var(--color-separator)"
|
|
2663
2709
|
},
|
|
2664
2710
|
".cm-completionIcon": {
|
|
2665
2711
|
display: "none"
|
|
2666
2712
|
},
|
|
2667
2713
|
".cm-completionLabel": {
|
|
2668
|
-
color: "var(--
|
|
2714
|
+
color: "var(--color-description)",
|
|
2669
2715
|
padding: "0 4px"
|
|
2670
2716
|
},
|
|
2671
2717
|
".cm-completionMatchedText": {
|
|
2672
|
-
color: "var(--
|
|
2718
|
+
color: "var(--color-base-surface-text)",
|
|
2673
2719
|
textDecoration: "none !important"
|
|
2674
2720
|
},
|
|
2675
2721
|
/**
|
|
@@ -2693,7 +2739,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2693
2739
|
backgroundColor: "var(--surface-bg)"
|
|
2694
2740
|
},
|
|
2695
2741
|
".cm-panel input, .cm-panel button, .cm-panel label": {
|
|
2696
|
-
color: "var(--
|
|
2742
|
+
color: "var(--color-subdued)",
|
|
2697
2743
|
fontSize: "14px",
|
|
2698
2744
|
all: "unset",
|
|
2699
2745
|
margin: "3px !important",
|
|
@@ -2701,10 +2747,10 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2701
2747
|
outline: "1px solid transparent"
|
|
2702
2748
|
},
|
|
2703
2749
|
".cm-panel input, .cm-panel button": {
|
|
2704
|
-
backgroundColor: "var(--
|
|
2750
|
+
backgroundColor: "var(--color-input-surface)"
|
|
2705
2751
|
},
|
|
2706
2752
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2707
|
-
outline: "1px solid var(--
|
|
2753
|
+
outline: "1px solid var(--color-neutral-focus-indicator)"
|
|
2708
2754
|
},
|
|
2709
2755
|
".cm-panel label": {
|
|
2710
2756
|
display: "inline-flex",
|
|
@@ -2717,34 +2763,33 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2717
2763
|
height: "8px",
|
|
2718
2764
|
marginRight: "6px !important",
|
|
2719
2765
|
padding: "2px !important",
|
|
2720
|
-
color: "var(--
|
|
2766
|
+
color: "var(--color-neutral-focus-indicator)"
|
|
2721
2767
|
},
|
|
2722
2768
|
".cm-panel button": {
|
|
2723
2769
|
"&:hover": {
|
|
2724
|
-
// TODO(burdon): Replace with layer and @apply bg-
|
|
2725
|
-
backgroundColor: "var(--
|
|
2770
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
|
|
2771
|
+
backgroundColor: "var(--color-accent-surface-hover) !important"
|
|
2726
2772
|
},
|
|
2727
2773
|
"&:active": {
|
|
2728
|
-
backgroundColor: "var(--
|
|
2774
|
+
backgroundColor: "var(--color-accent-surface-hover)"
|
|
2729
2775
|
}
|
|
2730
2776
|
},
|
|
2731
2777
|
".cm-panel.cm-search": {
|
|
2732
2778
|
padding: "4px",
|
|
2733
|
-
borderTop: "1px solid var(--
|
|
2779
|
+
borderTop: "1px solid var(--color-separator)"
|
|
2734
2780
|
}
|
|
2735
2781
|
});
|
|
2736
2782
|
var editorGutter = EditorView13.theme({
|
|
2737
2783
|
".cm-gutters": {
|
|
2738
2784
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2739
|
-
background: "var(--
|
|
2785
|
+
background: "var(--color-base-surface) !important",
|
|
2740
2786
|
paddingRight: "1rem"
|
|
2741
2787
|
}
|
|
2742
2788
|
});
|
|
2743
2789
|
var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
2744
|
-
//
|
|
2790
|
+
// Main content.
|
|
2745
2791
|
".cm-scroller": {
|
|
2746
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2747
|
-
fontSize: "16px"
|
|
2792
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2748
2793
|
},
|
|
2749
2794
|
// Maintain defaults for UI components.
|
|
2750
2795
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2754,9 +2799,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2754
2799
|
});
|
|
2755
2800
|
|
|
2756
2801
|
// src/extensions/focus.ts
|
|
2757
|
-
import { StateEffect as
|
|
2802
|
+
import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
|
|
2758
2803
|
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
2759
|
-
var focusEffect =
|
|
2804
|
+
var focusEffect = StateEffect6.define();
|
|
2760
2805
|
var focusField = StateField5.define({
|
|
2761
2806
|
create: () => false,
|
|
2762
2807
|
update: (value, tr) => {
|
|
@@ -2784,9 +2829,32 @@ var focus = [
|
|
|
2784
2829
|
})
|
|
2785
2830
|
];
|
|
2786
2831
|
|
|
2832
|
+
// src/extensions/scroll-past-end.ts
|
|
2833
|
+
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2834
|
+
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2835
|
+
height = 1e3;
|
|
2836
|
+
attrs = {
|
|
2837
|
+
style: "padding-bottom: 1000px"
|
|
2838
|
+
};
|
|
2839
|
+
update({ view }) {
|
|
2840
|
+
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2841
|
+
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2842
|
+
if (height >= 0 && height !== this.height) {
|
|
2843
|
+
this.height = height;
|
|
2844
|
+
this.attrs = {
|
|
2845
|
+
style: `padding-bottom: ${height}px`
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
});
|
|
2850
|
+
var scrollPastEnd = () => [
|
|
2851
|
+
scrollPastEndPlugin,
|
|
2852
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null)
|
|
2853
|
+
];
|
|
2854
|
+
|
|
2787
2855
|
// src/extensions/factories.ts
|
|
2788
|
-
var
|
|
2789
|
-
var tabbable =
|
|
2856
|
+
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2857
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2790
2858
|
tabindex: "0"
|
|
2791
2859
|
});
|
|
2792
2860
|
var filterChars = (chars) => {
|
|
@@ -2839,13 +2907,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2839
2907
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2840
2908
|
return [
|
|
2841
2909
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
F: __dxlog_file10,
|
|
2845
|
-
L: 132,
|
|
2846
|
-
S: void 0,
|
|
2847
|
-
C: (f, a) => f(...a)
|
|
2848
|
-
});
|
|
2910
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2911
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2849
2912
|
}),
|
|
2850
2913
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2851
2914
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2854,7 +2917,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2854
2917
|
props.drawSelection && drawSelection({
|
|
2855
2918
|
cursorBlinkRate: 1200
|
|
2856
2919
|
}),
|
|
2857
|
-
props.editable !== void 0 &&
|
|
2920
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2858
2921
|
props.focus && focus,
|
|
2859
2922
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2860
2923
|
props.history && history(),
|
|
@@ -2862,9 +2925,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2862
2925
|
lineNumbers(),
|
|
2863
2926
|
editorGutter
|
|
2864
2927
|
],
|
|
2865
|
-
props.lineWrapping &&
|
|
2928
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2866
2929
|
props.placeholder && placeholder2(props.placeholder),
|
|
2867
2930
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2931
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
2932
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
2933
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
2934
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
2935
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
2936
|
+
// depend on being able to populate the doc themselves.
|
|
2937
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2868
2938
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2869
2939
|
props.tabbable && tabbable,
|
|
2870
2940
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2894,12 +2964,12 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2894
2964
|
};
|
|
2895
2965
|
var grow = {
|
|
2896
2966
|
editor: {
|
|
2897
|
-
className: "
|
|
2967
|
+
className: "h-full w-full"
|
|
2898
2968
|
}
|
|
2899
2969
|
};
|
|
2900
2970
|
var fullWidth = {
|
|
2901
2971
|
editor: {
|
|
2902
|
-
className: "
|
|
2972
|
+
className: "w-full"
|
|
2903
2973
|
}
|
|
2904
2974
|
};
|
|
2905
2975
|
var defaultThemeSlots = grow;
|
|
@@ -2907,24 +2977,29 @@ var defaultStyles = {
|
|
|
2907
2977
|
dark: vscodeDarkStyle,
|
|
2908
2978
|
light: vscodeLightStyle
|
|
2909
2979
|
};
|
|
2910
|
-
var createThemeExtensions = ({ monospace,
|
|
2980
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2911
2981
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2912
2982
|
return [
|
|
2913
2983
|
baseTheme,
|
|
2914
|
-
|
|
2984
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2915
2985
|
createFontTheme({
|
|
2916
2986
|
monospace
|
|
2917
2987
|
}),
|
|
2918
2988
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2919
|
-
slots.editor?.className &&
|
|
2989
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2920
2990
|
class: slots.editor.className
|
|
2921
2991
|
}),
|
|
2922
|
-
slots.content?.className &&
|
|
2992
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2923
2993
|
class: slots.content.className
|
|
2924
2994
|
}),
|
|
2925
|
-
slots.
|
|
2995
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2926
2996
|
constructor(view) {
|
|
2927
|
-
|
|
2997
|
+
if (slots.scroller?.className) {
|
|
2998
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
2999
|
+
}
|
|
3000
|
+
if (scrollbarThin) {
|
|
3001
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
3002
|
+
}
|
|
2928
3003
|
}
|
|
2929
3004
|
})
|
|
2930
3005
|
].filter(isTruthy2);
|
|
@@ -2942,8 +3017,8 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2942
3017
|
channel: `awareness.${id}`,
|
|
2943
3018
|
peerId: identity.identityKey.toHex(),
|
|
2944
3019
|
info: {
|
|
2945
|
-
darkColor: `var(--
|
|
2946
|
-
lightColor: `var(--
|
|
3020
|
+
darkColor: `var(--color-${hue}-border)`,
|
|
3021
|
+
lightColor: `var(--color-${hue}-border)`,
|
|
2947
3022
|
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex())
|
|
2948
3023
|
}
|
|
2949
3024
|
})));
|
|
@@ -2953,7 +3028,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2953
3028
|
|
|
2954
3029
|
// src/extensions/folding.ts
|
|
2955
3030
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2956
|
-
import { EditorView as
|
|
3031
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2957
3032
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2958
3033
|
var folding = () => {
|
|
2959
3034
|
return [
|
|
@@ -2961,13 +3036,14 @@ var folding = () => {
|
|
|
2961
3036
|
placeholderDOM: () => Domino2.of("span").root
|
|
2962
3037
|
}),
|
|
2963
3038
|
foldGutter({
|
|
3039
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2964
3040
|
markerDOM: (open) => {
|
|
2965
|
-
return Domino2.of("div").classNames("flex
|
|
3041
|
+
return Domino2.of("div").classNames("flex h-full justify-center items-center").append(Domino2.of("svg", Domino2.SVG).classNames(mx4("w-4 h-4 cursor-pointer", open && "rotate-90")).append(Domino2.of("use", Domino2.SVG).attributes({
|
|
2966
3042
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2967
3043
|
}))).root;
|
|
2968
3044
|
}
|
|
2969
3045
|
}),
|
|
2970
|
-
|
|
3046
|
+
EditorView17.theme({
|
|
2971
3047
|
".cm-foldGutter": {
|
|
2972
3048
|
opacity: 0.3,
|
|
2973
3049
|
transition: "opacity 0.3s",
|
|
@@ -2981,7 +3057,7 @@ var folding = () => {
|
|
|
2981
3057
|
};
|
|
2982
3058
|
|
|
2983
3059
|
// src/extensions/hashtag.ts
|
|
2984
|
-
import { Decoration as Decoration8, EditorView as
|
|
3060
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
2985
3061
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
2986
3062
|
var TagWidget = class extends WidgetType4 {
|
|
2987
3063
|
_text;
|
|
@@ -3002,7 +3078,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3002
3078
|
})
|
|
3003
3079
|
});
|
|
3004
3080
|
var hashtag = () => [
|
|
3005
|
-
|
|
3081
|
+
ViewPlugin13.fromClass(class {
|
|
3006
3082
|
tags;
|
|
3007
3083
|
constructor(view) {
|
|
3008
3084
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3012,11 +3088,11 @@ var hashtag = () => [
|
|
|
3012
3088
|
}
|
|
3013
3089
|
}, {
|
|
3014
3090
|
decorations: (instance) => instance.tags,
|
|
3015
|
-
provide: (plugin) =>
|
|
3091
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
3016
3092
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3017
3093
|
})
|
|
3018
3094
|
}),
|
|
3019
|
-
|
|
3095
|
+
EditorView18.theme({
|
|
3020
3096
|
".cm-tag": {
|
|
3021
3097
|
borderRadius: "4px",
|
|
3022
3098
|
marginRight: "6px",
|
|
@@ -3071,18 +3147,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3071
3147
|
};
|
|
3072
3148
|
|
|
3073
3149
|
// src/extensions/listener.ts
|
|
3074
|
-
import { EditorView as
|
|
3150
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3075
3151
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3076
3152
|
var listener = ({ onFocus, onChange }) => {
|
|
3077
3153
|
return [
|
|
3078
|
-
onFocus &&
|
|
3154
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3079
3155
|
onFocus({
|
|
3080
3156
|
id: state.facet(documentId),
|
|
3081
3157
|
focusing
|
|
3082
3158
|
});
|
|
3083
3159
|
return null;
|
|
3084
3160
|
}),
|
|
3085
|
-
onChange &&
|
|
3161
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3086
3162
|
if (docChanged) {
|
|
3087
3163
|
onChange({
|
|
3088
3164
|
id: state.facet(documentId),
|
|
@@ -3097,7 +3173,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3097
3173
|
import { snippet } from "@codemirror/autocomplete";
|
|
3098
3174
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3099
3175
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3100
|
-
import { EditorView as
|
|
3176
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3101
3177
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3102
3178
|
var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
3103
3179
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4186,7 +4262,7 @@ var getFormatting = (state) => {
|
|
|
4186
4262
|
};
|
|
4187
4263
|
};
|
|
4188
4264
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4189
|
-
return
|
|
4265
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4190
4266
|
if (update2.docChanged || update2.selectionSet) {
|
|
4191
4267
|
onStateChange(getFormatting(update2.state));
|
|
4192
4268
|
}
|
|
@@ -4247,8 +4323,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4247
4323
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4248
4324
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4249
4325
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4250
|
-
import {
|
|
4251
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4326
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4252
4327
|
import { languages } from "@codemirror/language-data";
|
|
4253
4328
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4254
4329
|
import { isTruthy as isTruthy3 } from "@dxos/util";
|
|
@@ -4369,30 +4444,38 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4369
4444
|
],
|
|
4370
4445
|
class: "font-mono"
|
|
4371
4446
|
},
|
|
4372
|
-
// Headings
|
|
4447
|
+
// Headings — use CSS properties only (no class:) so CodeMirror generates scoped CSS via
|
|
4448
|
+
// StyleModule that overrides vscodeDarkStyle's t.heading rule. When class: is present,
|
|
4449
|
+
// HighlightStyle silently ignores all other CSS properties (they're mutually exclusive).
|
|
4450
|
+
// Font sizes use Tailwind v4 CSS variables so nothing is hardcoded.
|
|
4451
|
+
{
|
|
4452
|
+
tag: tags.heading,
|
|
4453
|
+
color: "var(--color-cm-heading) !important",
|
|
4454
|
+
fontWeight: "300"
|
|
4455
|
+
},
|
|
4373
4456
|
{
|
|
4374
4457
|
tag: tags.heading1,
|
|
4375
|
-
|
|
4458
|
+
...markdownTheme.heading(1)
|
|
4376
4459
|
},
|
|
4377
4460
|
{
|
|
4378
4461
|
tag: tags.heading2,
|
|
4379
|
-
|
|
4462
|
+
...markdownTheme.heading(2)
|
|
4380
4463
|
},
|
|
4381
4464
|
{
|
|
4382
4465
|
tag: tags.heading3,
|
|
4383
|
-
|
|
4466
|
+
...markdownTheme.heading(3)
|
|
4384
4467
|
},
|
|
4385
4468
|
{
|
|
4386
4469
|
tag: tags.heading4,
|
|
4387
|
-
|
|
4470
|
+
...markdownTheme.heading(4)
|
|
4388
4471
|
},
|
|
4389
4472
|
{
|
|
4390
4473
|
tag: tags.heading5,
|
|
4391
|
-
|
|
4474
|
+
...markdownTheme.heading(5)
|
|
4392
4475
|
},
|
|
4393
4476
|
{
|
|
4394
4477
|
tag: tags.heading6,
|
|
4395
|
-
|
|
4478
|
+
...markdownTheme.heading(6)
|
|
4396
4479
|
},
|
|
4397
4480
|
// Emphasis.
|
|
4398
4481
|
{
|
|
@@ -4447,15 +4530,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4447
4530
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4448
4531
|
base: markdownLanguage2,
|
|
4449
4532
|
// Languages for syntax highlighting fenced code blocks.
|
|
4533
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4450
4534
|
defaultCodeLanguage: jsonLanguage,
|
|
4451
|
-
codeLanguages:
|
|
4535
|
+
codeLanguages: [
|
|
4536
|
+
...options.codeLanguages ?? [],
|
|
4537
|
+
...languages
|
|
4538
|
+
],
|
|
4452
4539
|
// Don't complete HTML tags.
|
|
4453
4540
|
completeHTMLTags: false,
|
|
4454
4541
|
// Parser extensions.
|
|
4455
4542
|
extensions: [
|
|
4456
4543
|
// GFM provided by default.
|
|
4457
4544
|
markdownTagsExtensions,
|
|
4458
|
-
...options.extensions ?? defaultExtensions()
|
|
4545
|
+
...options.extensions ?? defaultExtensions(),
|
|
4546
|
+
// Disable folding for fenced code blocks by overriding foldNodeProp.
|
|
4547
|
+
// Note: returning null from foldService does not prevent syntaxFolding fallback,
|
|
4548
|
+
// so we must override the node prop directly on the FencedCode node type.
|
|
4549
|
+
noFencedCodeFolding
|
|
4459
4550
|
]
|
|
4460
4551
|
}),
|
|
4461
4552
|
// Custom styles.
|
|
@@ -4470,18 +4561,13 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4470
4561
|
].filter(isTruthy3))
|
|
4471
4562
|
];
|
|
4472
4563
|
};
|
|
4473
|
-
var
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
]
|
|
4479
|
-
|
|
4480
|
-
"xml",
|
|
4481
|
-
"xhtml"
|
|
4482
|
-
],
|
|
4483
|
-
load: async () => xml()
|
|
4484
|
-
});
|
|
4564
|
+
var noFencedCodeFolding = {
|
|
4565
|
+
props: [
|
|
4566
|
+
foldNodeProp.add({
|
|
4567
|
+
FencedCode: () => null
|
|
4568
|
+
})
|
|
4569
|
+
]
|
|
4570
|
+
};
|
|
4485
4571
|
var defaultExtensions = () => [
|
|
4486
4572
|
noSetExtHeading,
|
|
4487
4573
|
noHtml
|
|
@@ -4501,19 +4587,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4501
4587
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4502
4588
|
});
|
|
4503
4589
|
var convertTreeToJson = (state) => {
|
|
4504
|
-
const treeToJson = (
|
|
4590
|
+
const treeToJson = (cursor) => {
|
|
4505
4591
|
const node = {
|
|
4506
|
-
type:
|
|
4507
|
-
from:
|
|
4508
|
-
to:
|
|
4509
|
-
text: state.doc.slice(
|
|
4592
|
+
type: cursor.type.name,
|
|
4593
|
+
from: cursor.from,
|
|
4594
|
+
to: cursor.to,
|
|
4595
|
+
text: state.doc.slice(cursor.from, cursor.to).toString(),
|
|
4510
4596
|
children: []
|
|
4511
4597
|
};
|
|
4512
|
-
if (
|
|
4598
|
+
if (cursor.firstChild()) {
|
|
4513
4599
|
do {
|
|
4514
|
-
node.children.push(treeToJson(
|
|
4515
|
-
} while (
|
|
4516
|
-
|
|
4600
|
+
node.children.push(treeToJson(cursor));
|
|
4601
|
+
} while (cursor.nextSibling());
|
|
4602
|
+
cursor.parent();
|
|
4517
4603
|
}
|
|
4518
4604
|
return node;
|
|
4519
4605
|
};
|
|
@@ -4522,17 +4608,16 @@ var convertTreeToJson = (state) => {
|
|
|
4522
4608
|
|
|
4523
4609
|
// src/extensions/markdown/decorate.ts
|
|
4524
4610
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4525
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4526
|
-
import { Decoration as Decoration11, EditorView as
|
|
4611
|
+
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
|
|
4612
|
+
import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4527
4613
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4528
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4529
4614
|
|
|
4530
4615
|
// src/extensions/markdown/changes.ts
|
|
4531
4616
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4532
4617
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4533
|
-
import { ViewPlugin as
|
|
4618
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4534
4619
|
var adjustChanges = () => {
|
|
4535
|
-
return
|
|
4620
|
+
return ViewPlugin14.fromClass(class {
|
|
4536
4621
|
update(update2) {
|
|
4537
4622
|
const tree = syntaxTree4(update2.state);
|
|
4538
4623
|
const adjustments = [];
|
|
@@ -4674,7 +4759,7 @@ var getValidUrl = (str) => {
|
|
|
4674
4759
|
// src/extensions/markdown/image.ts
|
|
4675
4760
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4676
4761
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4677
|
-
import { Decoration as Decoration9, EditorView as
|
|
4762
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4678
4763
|
var image = (_options = {}) => {
|
|
4679
4764
|
return [
|
|
4680
4765
|
StateField7.define({
|
|
@@ -4685,10 +4770,10 @@ var image = (_options = {}) => {
|
|
|
4685
4770
|
if (!tr.docChanged && !tr.selection) {
|
|
4686
4771
|
return value;
|
|
4687
4772
|
}
|
|
4688
|
-
const
|
|
4773
|
+
const cursor = tr.state.selection.main.head;
|
|
4689
4774
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4690
|
-
let from = Math.min(
|
|
4691
|
-
let to = Math.max(
|
|
4775
|
+
let from = Math.min(cursor, oldCursor);
|
|
4776
|
+
let to = Math.max(cursor, oldCursor);
|
|
4692
4777
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4693
4778
|
from = Math.min(from, fromB);
|
|
4694
4779
|
to = Math.max(to, toB);
|
|
@@ -4702,19 +4787,19 @@ var image = (_options = {}) => {
|
|
|
4702
4787
|
add: buildDecorations(tr.state, from, to)
|
|
4703
4788
|
});
|
|
4704
4789
|
},
|
|
4705
|
-
provide: (field) =>
|
|
4790
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4706
4791
|
})
|
|
4707
4792
|
];
|
|
4708
4793
|
};
|
|
4709
4794
|
var buildDecorations = (state, from, to) => {
|
|
4710
4795
|
const decorations2 = [];
|
|
4711
|
-
const
|
|
4796
|
+
const cursor = state.selection.main.head;
|
|
4712
4797
|
syntaxTree5(state).iterate({
|
|
4713
4798
|
enter: (node) => {
|
|
4714
4799
|
if (node.name === "Image") {
|
|
4715
4800
|
const urlNode = node.node.getChild("URL");
|
|
4716
4801
|
if (urlNode) {
|
|
4717
|
-
const hide2 = state.readOnly ||
|
|
4802
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4718
4803
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4719
4804
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4720
4805
|
return;
|
|
@@ -4762,10 +4847,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4762
4847
|
};
|
|
4763
4848
|
|
|
4764
4849
|
// src/extensions/markdown/styles.ts
|
|
4765
|
-
import { EditorView as
|
|
4850
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4766
4851
|
var bulletListIndentationWidth = 24;
|
|
4767
4852
|
var orderedListIndentationWidth = 36;
|
|
4768
|
-
var formattingStyles =
|
|
4853
|
+
var formattingStyles = EditorView22.theme({
|
|
4769
4854
|
/**
|
|
4770
4855
|
* Horizontal rule.
|
|
4771
4856
|
*/
|
|
@@ -4774,7 +4859,7 @@ var formattingStyles = EditorView21.theme({
|
|
|
4774
4859
|
width: "100%",
|
|
4775
4860
|
height: "0",
|
|
4776
4861
|
verticalAlign: "middle",
|
|
4777
|
-
borderTop: "1px solid var(--
|
|
4862
|
+
borderTop: "1px solid var(--color-cm-separator)",
|
|
4778
4863
|
opacity: 0.5
|
|
4779
4864
|
},
|
|
4780
4865
|
/**
|
|
@@ -4797,19 +4882,44 @@ var formattingStyles = EditorView21.theme({
|
|
|
4797
4882
|
* Blockquote.
|
|
4798
4883
|
*/
|
|
4799
4884
|
"& .cm-blockquote": {
|
|
4800
|
-
background: "var(--
|
|
4801
|
-
borderLeft: "2px solid var(--
|
|
4885
|
+
background: "var(--color-cm-codeblock)",
|
|
4886
|
+
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4802
4887
|
paddingLeft: "1rem",
|
|
4803
|
-
margin:
|
|
4888
|
+
margin: 0
|
|
4804
4889
|
},
|
|
4805
4890
|
/**
|
|
4806
4891
|
* Code and codeblocks.
|
|
4807
4892
|
*/
|
|
4893
|
+
"& code": {
|
|
4894
|
+
fontFamily: fontMono,
|
|
4895
|
+
color: "var(--color-cm-code)",
|
|
4896
|
+
whiteSpace: "nowrap"
|
|
4897
|
+
},
|
|
4808
4898
|
"& .cm-code": {
|
|
4809
|
-
fontFamily: fontMono
|
|
4899
|
+
fontFamily: fontMono,
|
|
4900
|
+
color: "var(--color-cm-code)"
|
|
4810
4901
|
},
|
|
4811
|
-
|
|
4812
|
-
|
|
4902
|
+
// Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
|
|
4903
|
+
// Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
|
|
4904
|
+
// so constrain them to the target 24px height.
|
|
4905
|
+
"& .cm-code-inline": {
|
|
4906
|
+
fontFamily: fontMono,
|
|
4907
|
+
height: "24px",
|
|
4908
|
+
// display: 'inline-flex',
|
|
4909
|
+
alignItems: "center",
|
|
4910
|
+
overflow: "hidden",
|
|
4911
|
+
whiteSpace: "nowrap",
|
|
4912
|
+
color: "var(--color-cm-code-inline)"
|
|
4913
|
+
},
|
|
4914
|
+
"& .cm-code-mark": {
|
|
4915
|
+
fontFamily: fontMono,
|
|
4916
|
+
height: "24px",
|
|
4917
|
+
display: "inline-flex",
|
|
4918
|
+
alignItems: "center",
|
|
4919
|
+
overflow: "hidden"
|
|
4920
|
+
},
|
|
4921
|
+
"& .cm-codeblock-line": {
|
|
4922
|
+
background: "var(--color-cm-codeblock)",
|
|
4813
4923
|
paddingInline: "1rem !important"
|
|
4814
4924
|
},
|
|
4815
4925
|
"& .cm-codeblock-start": {
|
|
@@ -4838,16 +4948,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4838
4948
|
*/
|
|
4839
4949
|
".cm-table *": {
|
|
4840
4950
|
fontFamily: fontMono,
|
|
4951
|
+
lineHeight: 1.5,
|
|
4841
4952
|
textDecoration: "none !important"
|
|
4842
4953
|
},
|
|
4843
4954
|
".cm-table-head": {
|
|
4844
4955
|
padding: "2px 16px 2px 0px",
|
|
4956
|
+
overflowWrap: "break-word",
|
|
4957
|
+
whiteSpace: "pre-wrap",
|
|
4958
|
+
wordBreak: "keep-all",
|
|
4845
4959
|
textAlign: "left",
|
|
4846
|
-
|
|
4847
|
-
|
|
4960
|
+
color: "var(--color-subdued)",
|
|
4961
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4848
4962
|
},
|
|
4849
4963
|
".cm-table-cell": {
|
|
4850
|
-
padding: "2px 16px 2px 0px"
|
|
4964
|
+
padding: "2px 16px 2px 0px",
|
|
4965
|
+
overflowWrap: "break-word",
|
|
4966
|
+
whiteSpace: "pre-wrap",
|
|
4967
|
+
wordBreak: "keep-all",
|
|
4968
|
+
verticalAlign: "top"
|
|
4851
4969
|
},
|
|
4852
4970
|
/**
|
|
4853
4971
|
* Image.
|
|
@@ -4863,12 +4981,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4863
4981
|
},
|
|
4864
4982
|
".cm-image-with-loader": {
|
|
4865
4983
|
display: "block",
|
|
4866
|
-
opacity:
|
|
4984
|
+
opacity: 0,
|
|
4867
4985
|
transitionDuration: "350ms",
|
|
4868
4986
|
transitionProperty: "opacity"
|
|
4869
4987
|
},
|
|
4870
4988
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4871
|
-
opacity:
|
|
4989
|
+
opacity: 1
|
|
4872
4990
|
},
|
|
4873
4991
|
".cm-image-wrapper": {
|
|
4874
4992
|
"grid-template-columns": "1fr",
|
|
@@ -4887,17 +5005,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4887
5005
|
// src/extensions/markdown/table.ts
|
|
4888
5006
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4889
5007
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4890
|
-
import { Decoration as Decoration10, EditorView as
|
|
5008
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4891
5009
|
var table = (options = {}) => {
|
|
4892
5010
|
return StateField8.define({
|
|
4893
5011
|
create: (state) => update(state, options),
|
|
4894
5012
|
update: (_, tr) => update(tr.state, options),
|
|
4895
|
-
provide: (field) =>
|
|
5013
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4896
5014
|
});
|
|
4897
5015
|
};
|
|
4898
5016
|
var update = (state, _options) => {
|
|
4899
5017
|
const builder = new RangeSetBuilder4();
|
|
4900
|
-
const
|
|
5018
|
+
const cursor = state.selection.main.head;
|
|
4901
5019
|
const tables = [];
|
|
4902
5020
|
const getTable = () => tables[tables.length - 1];
|
|
4903
5021
|
const getRow = () => {
|
|
@@ -4935,7 +5053,7 @@ var update = (state, _options) => {
|
|
|
4935
5053
|
}
|
|
4936
5054
|
});
|
|
4937
5055
|
tables.forEach((table2) => {
|
|
4938
|
-
const replace = state.readOnly ||
|
|
5056
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4939
5057
|
if (replace) {
|
|
4940
5058
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4941
5059
|
block: true,
|
|
@@ -4949,6 +5067,26 @@ var update = (state, _options) => {
|
|
|
4949
5067
|
});
|
|
4950
5068
|
return builder.finish();
|
|
4951
5069
|
};
|
|
5070
|
+
var renderCellContent = (el, text) => {
|
|
5071
|
+
const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
|
|
5072
|
+
for (const part of parts) {
|
|
5073
|
+
if (part.length > 2 && part.startsWith("`") && part.endsWith("`")) {
|
|
5074
|
+
const code = document.createElement("code");
|
|
5075
|
+
code.textContent = part.slice(1, -1);
|
|
5076
|
+
el.appendChild(code);
|
|
5077
|
+
} else if (part.startsWith("**") && part.endsWith("**") || part.startsWith("__") && part.endsWith("__")) {
|
|
5078
|
+
const strong = document.createElement("strong");
|
|
5079
|
+
strong.textContent = part.slice(2, -2);
|
|
5080
|
+
el.appendChild(strong);
|
|
5081
|
+
} else if (part.startsWith("*") && part.endsWith("*") || part.startsWith("_") && part.endsWith("_")) {
|
|
5082
|
+
const em = document.createElement("em");
|
|
5083
|
+
em.textContent = part.slice(1, -1);
|
|
5084
|
+
el.appendChild(em);
|
|
5085
|
+
} else {
|
|
5086
|
+
el.appendChild(document.createTextNode(part));
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
};
|
|
4952
5090
|
var TableWidget = class extends WidgetType6 {
|
|
4953
5091
|
_table;
|
|
4954
5092
|
constructor(_table) {
|
|
@@ -4968,7 +5106,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4968
5106
|
this._table.header?.forEach((cell) => {
|
|
4969
5107
|
const th = document.createElement("th");
|
|
4970
5108
|
th.setAttribute("class", "cm-table-head");
|
|
4971
|
-
tr.appendChild(th)
|
|
5109
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
4972
5110
|
});
|
|
4973
5111
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
4974
5112
|
this._table.rows?.forEach((row) => {
|
|
@@ -4976,7 +5114,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4976
5114
|
row.forEach((cell) => {
|
|
4977
5115
|
const td = document.createElement("td");
|
|
4978
5116
|
td.setAttribute("class", "cm-table-cell");
|
|
4979
|
-
tr2.appendChild(td)
|
|
5117
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
4980
5118
|
});
|
|
4981
5119
|
});
|
|
4982
5120
|
return div;
|
|
@@ -4984,7 +5122,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4984
5122
|
};
|
|
4985
5123
|
|
|
4986
5124
|
// src/extensions/markdown/decorate.ts
|
|
4987
|
-
var
|
|
5125
|
+
var __dxlog_file12 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/markdown/decorate.ts";
|
|
4988
5126
|
var Unicode = {
|
|
4989
5127
|
emDash: "\u2014",
|
|
4990
5128
|
bullet: "\u2022",
|
|
@@ -5007,7 +5145,6 @@ var LinkButton = class extends WidgetType7 {
|
|
|
5007
5145
|
eq(other) {
|
|
5008
5146
|
return this.url === other.url;
|
|
5009
5147
|
}
|
|
5010
|
-
// TODO(burdon): Create icon and link directly without react?
|
|
5011
5148
|
toDOM(view) {
|
|
5012
5149
|
const el = document.createElement("span");
|
|
5013
5150
|
this.render(el, {
|
|
@@ -5084,10 +5221,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5084
5221
|
class: "cm-code cm-codeblock-line"
|
|
5085
5222
|
});
|
|
5086
5223
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5087
|
-
class:
|
|
5224
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5088
5225
|
});
|
|
5089
5226
|
var fencedCodeLineLast = Decoration11.line({
|
|
5090
|
-
class:
|
|
5227
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5091
5228
|
});
|
|
5092
5229
|
var commentBlockLine = fencedCodeLine;
|
|
5093
5230
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5119,15 +5256,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5119
5256
|
const { state } = view;
|
|
5120
5257
|
const headerLevels = [];
|
|
5121
5258
|
const getHeaderLevels = (node, level) => {
|
|
5122
|
-
invariant4(level > 0, void 0, {
|
|
5123
|
-
F: __dxlog_file11,
|
|
5124
|
-
L: 180,
|
|
5125
|
-
S: void 0,
|
|
5126
|
-
A: [
|
|
5127
|
-
"level > 0",
|
|
5128
|
-
""
|
|
5129
|
-
]
|
|
5130
|
-
});
|
|
5259
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5131
5260
|
if (level > headerLevels.length) {
|
|
5132
5261
|
const len = headerLevels.length;
|
|
5133
5262
|
headerLevels.length = level;
|
|
@@ -5158,15 +5287,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5158
5287
|
listLevels.pop();
|
|
5159
5288
|
};
|
|
5160
5289
|
const getCurrentListLevel = () => {
|
|
5161
|
-
invariant4(listLevels.length, void 0, {
|
|
5162
|
-
F: __dxlog_file11,
|
|
5163
|
-
L: 202,
|
|
5164
|
-
S: void 0,
|
|
5165
|
-
A: [
|
|
5166
|
-
"listLevels.length",
|
|
5167
|
-
""
|
|
5168
|
-
]
|
|
5169
|
-
});
|
|
5290
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5170
5291
|
return listLevels[listLevels.length - 1];
|
|
5171
5292
|
};
|
|
5172
5293
|
const enterNode = (node) => {
|
|
@@ -5204,13 +5325,13 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5204
5325
|
deco: hide
|
|
5205
5326
|
});
|
|
5206
5327
|
} else {
|
|
5207
|
-
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
|
5328
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + "). ";
|
|
5208
5329
|
if (num.length) {
|
|
5209
5330
|
atomicDecoRanges.push({
|
|
5210
5331
|
from: mark.from,
|
|
5211
5332
|
to: mark.from + len,
|
|
5212
5333
|
deco: Decoration11.replace({
|
|
5213
|
-
widget: new TextWidget(num, markdownTheme.heading(level))
|
|
5334
|
+
widget: new TextWidget(num, markdownTheme.heading(level).className)
|
|
5214
5335
|
})
|
|
5215
5336
|
});
|
|
5216
5337
|
}
|
|
@@ -5387,11 +5508,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5387
5508
|
}
|
|
5388
5509
|
decoRanges.push({
|
|
5389
5510
|
from: marks[0].to,
|
|
5390
|
-
to: marks[1].from,
|
|
5511
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5391
5512
|
deco: Decoration11.mark({
|
|
5392
5513
|
tagName: "a",
|
|
5393
5514
|
attributes: {
|
|
5394
|
-
class: "cm-link",
|
|
5515
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5395
5516
|
href: url,
|
|
5396
5517
|
rel: "noreferrer",
|
|
5397
5518
|
target: "_blank"
|
|
@@ -5469,18 +5590,21 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5469
5590
|
deco.add(from, to, d);
|
|
5470
5591
|
}
|
|
5471
5592
|
const atomicDeco = new RangeSetBuilder5();
|
|
5472
|
-
for (const { from, to, deco:
|
|
5473
|
-
|
|
5593
|
+
for (const { from, to, deco: deco2 } of atomicDecoRanges) {
|
|
5594
|
+
if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
|
|
5595
|
+
continue;
|
|
5596
|
+
}
|
|
5597
|
+
atomicDeco.add(from, to, deco2);
|
|
5474
5598
|
}
|
|
5475
5599
|
return {
|
|
5476
5600
|
deco: deco.finish(),
|
|
5477
5601
|
atomicDeco: atomicDeco.finish()
|
|
5478
5602
|
};
|
|
5479
5603
|
};
|
|
5480
|
-
var forceUpdate =
|
|
5604
|
+
var forceUpdate = StateEffect7.define();
|
|
5481
5605
|
var decorateMarkdown = (options = {}) => {
|
|
5482
5606
|
return [
|
|
5483
|
-
|
|
5607
|
+
ViewPlugin15.fromClass(class {
|
|
5484
5608
|
deco;
|
|
5485
5609
|
atomicDeco;
|
|
5486
5610
|
pendingUpdate;
|
|
@@ -5515,9 +5639,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5515
5639
|
}
|
|
5516
5640
|
}, {
|
|
5517
5641
|
provide: (plugin) => [
|
|
5518
|
-
Prec4.low(
|
|
5519
|
-
|
|
5520
|
-
|
|
5642
|
+
Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5643
|
+
EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5644
|
+
EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5521
5645
|
]
|
|
5522
5646
|
}),
|
|
5523
5647
|
image(),
|
|
@@ -5549,8 +5673,7 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5549
5673
|
return {
|
|
5550
5674
|
pos: link.from,
|
|
5551
5675
|
end: link.to,
|
|
5552
|
-
|
|
5553
|
-
// above: true,
|
|
5676
|
+
above: true,
|
|
5554
5677
|
create: () => {
|
|
5555
5678
|
const el = document.createElement("div");
|
|
5556
5679
|
el.className = tooltipContent({});
|
|
@@ -5566,16 +5689,13 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5566
5689
|
};
|
|
5567
5690
|
}
|
|
5568
5691
|
};
|
|
5569
|
-
}, {
|
|
5570
|
-
// NOTE: 0 = default of 300ms.
|
|
5571
|
-
hoverTime: 1
|
|
5572
5692
|
});
|
|
5573
5693
|
};
|
|
5574
5694
|
|
|
5575
5695
|
// src/extensions/mention.ts
|
|
5576
5696
|
import { autocompletion } from "@codemirror/autocomplete";
|
|
5577
|
-
import { log as
|
|
5578
|
-
var
|
|
5697
|
+
import { log as log9 } from "@dxos/log";
|
|
5698
|
+
var __dxlog_file13 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/mention.ts";
|
|
5579
5699
|
var mention = ({ debug, onSearch }) => {
|
|
5580
5700
|
return autocompletion({
|
|
5581
5701
|
// TODO(burdon): Not working.
|
|
@@ -5587,14 +5707,9 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5587
5707
|
icons: false,
|
|
5588
5708
|
override: [
|
|
5589
5709
|
(context) => {
|
|
5590
|
-
|
|
5710
|
+
log9.info("completion context", {
|
|
5591
5711
|
context
|
|
5592
|
-
}, {
|
|
5593
|
-
F: __dxlog_file12,
|
|
5594
|
-
L: 27,
|
|
5595
|
-
S: void 0,
|
|
5596
|
-
C: (f, a) => f(...a)
|
|
5597
|
-
});
|
|
5712
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5598
5713
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5599
5714
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5600
5715
|
return null;
|
|
@@ -5611,8 +5726,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5611
5726
|
};
|
|
5612
5727
|
|
|
5613
5728
|
// src/extensions/modal.ts
|
|
5614
|
-
import { StateEffect as
|
|
5615
|
-
var modalStateEffect =
|
|
5729
|
+
import { StateEffect as StateEffect8, StateField as StateField9 } from "@codemirror/state";
|
|
5730
|
+
var modalStateEffect = StateEffect8.define();
|
|
5616
5731
|
var modalStateField = StateField9.define({
|
|
5617
5732
|
create: () => false,
|
|
5618
5733
|
update: (value, tr) => {
|
|
@@ -5673,7 +5788,7 @@ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
|
|
|
5673
5788
|
import { StateField as StateField10 } from "@codemirror/state";
|
|
5674
5789
|
import { Facet as Facet2 } from "@codemirror/state";
|
|
5675
5790
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
5676
|
-
var
|
|
5791
|
+
var __dxlog_file14 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/tree.ts";
|
|
5677
5792
|
var itemToJSON = ({ type, index, level, lineRange, contentRange, children }) => {
|
|
5678
5793
|
return {
|
|
5679
5794
|
type,
|
|
@@ -5827,15 +5942,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5827
5942
|
break;
|
|
5828
5943
|
}
|
|
5829
5944
|
case "BulletList": {
|
|
5830
|
-
invariant5(current, void 0, {
|
|
5831
|
-
F: __dxlog_file13,
|
|
5832
|
-
L: 219,
|
|
5833
|
-
S: void 0,
|
|
5834
|
-
A: [
|
|
5835
|
-
"current",
|
|
5836
|
-
""
|
|
5837
|
-
]
|
|
5838
|
-
});
|
|
5945
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5839
5946
|
parent = current;
|
|
5840
5947
|
if (current) {
|
|
5841
5948
|
current.lineRange.to = current.node.from;
|
|
@@ -5844,15 +5951,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5844
5951
|
break;
|
|
5845
5952
|
}
|
|
5846
5953
|
case "ListItem": {
|
|
5847
|
-
invariant5(parent, void 0, {
|
|
5848
|
-
F: __dxlog_file13,
|
|
5849
|
-
L: 228,
|
|
5850
|
-
S: void 0,
|
|
5851
|
-
A: [
|
|
5852
|
-
"parent",
|
|
5853
|
-
""
|
|
5854
|
-
]
|
|
5855
|
-
});
|
|
5954
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5856
5955
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5857
5956
|
const docRange = {
|
|
5858
5957
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5886,42 +5985,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5886
5985
|
break;
|
|
5887
5986
|
}
|
|
5888
5987
|
case "ListMark": {
|
|
5889
|
-
invariant5(current, void 0, {
|
|
5890
|
-
F: __dxlog_file13,
|
|
5891
|
-
L: 272,
|
|
5892
|
-
S: void 0,
|
|
5893
|
-
A: [
|
|
5894
|
-
"current",
|
|
5895
|
-
""
|
|
5896
|
-
]
|
|
5897
|
-
});
|
|
5988
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5898
5989
|
current.type = "bullet";
|
|
5899
5990
|
current.contentRange.from = node.from + "- ".length;
|
|
5900
5991
|
break;
|
|
5901
5992
|
}
|
|
5902
5993
|
case "Task": {
|
|
5903
|
-
invariant5(current, void 0, {
|
|
5904
|
-
F: __dxlog_file13,
|
|
5905
|
-
L: 278,
|
|
5906
|
-
S: void 0,
|
|
5907
|
-
A: [
|
|
5908
|
-
"current",
|
|
5909
|
-
""
|
|
5910
|
-
]
|
|
5911
|
-
});
|
|
5994
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5912
5995
|
current.type = "task";
|
|
5913
5996
|
break;
|
|
5914
5997
|
}
|
|
5915
5998
|
case "TaskMarker": {
|
|
5916
|
-
invariant5(current, void 0, {
|
|
5917
|
-
F: __dxlog_file13,
|
|
5918
|
-
L: 283,
|
|
5919
|
-
S: void 0,
|
|
5920
|
-
A: [
|
|
5921
|
-
"current",
|
|
5922
|
-
""
|
|
5923
|
-
]
|
|
5924
|
-
});
|
|
5999
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5925
6000
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5926
6001
|
break;
|
|
5927
6002
|
}
|
|
@@ -5929,29 +6004,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5929
6004
|
},
|
|
5930
6005
|
leave: (node) => {
|
|
5931
6006
|
if (node.name === "BulletList") {
|
|
5932
|
-
invariant5(parent, void 0, {
|
|
5933
|
-
F: __dxlog_file13,
|
|
5934
|
-
L: 291,
|
|
5935
|
-
S: void 0,
|
|
5936
|
-
A: [
|
|
5937
|
-
"parent",
|
|
5938
|
-
""
|
|
5939
|
-
]
|
|
5940
|
-
});
|
|
6007
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5941
6008
|
prevSiblings[level--] = void 0;
|
|
5942
6009
|
parent = parent.parent;
|
|
5943
6010
|
}
|
|
5944
6011
|
}
|
|
5945
6012
|
});
|
|
5946
|
-
invariant5(tree, void 0, {
|
|
5947
|
-
F: __dxlog_file13,
|
|
5948
|
-
L: 298,
|
|
5949
|
-
S: void 0,
|
|
5950
|
-
A: [
|
|
5951
|
-
"tree",
|
|
5952
|
-
""
|
|
5953
|
-
]
|
|
5954
|
-
});
|
|
6013
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5955
6014
|
return tree;
|
|
5956
6015
|
};
|
|
5957
6016
|
return [
|
|
@@ -6236,17 +6295,17 @@ var commands = () => keymap11.of([
|
|
|
6236
6295
|
|
|
6237
6296
|
// src/extensions/outliner/outliner.ts
|
|
6238
6297
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6239
|
-
import { Decoration as Decoration12, EditorView as
|
|
6240
|
-
import { mx as
|
|
6298
|
+
import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6299
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
6241
6300
|
|
|
6242
6301
|
// src/extensions/outliner/editor.ts
|
|
6243
6302
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6244
|
-
import { ViewPlugin as
|
|
6245
|
-
import { log as
|
|
6246
|
-
var
|
|
6303
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6304
|
+
import { log as log10 } from "@dxos/log";
|
|
6305
|
+
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6247
6306
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6248
6307
|
var initialize = () => {
|
|
6249
|
-
return
|
|
6308
|
+
return ViewPlugin16.fromClass(class {
|
|
6250
6309
|
constructor(view) {
|
|
6251
6310
|
const first = view.state.doc.lineAt(0);
|
|
6252
6311
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6375,7 +6434,7 @@ var editor = () => [
|
|
|
6375
6434
|
cancel = true;
|
|
6376
6435
|
return;
|
|
6377
6436
|
}
|
|
6378
|
-
|
|
6437
|
+
log10("change", {
|
|
6379
6438
|
item,
|
|
6380
6439
|
line: {
|
|
6381
6440
|
from: line.from,
|
|
@@ -6393,35 +6452,20 @@ var editor = () => [
|
|
|
6393
6452
|
text: insert.toString(),
|
|
6394
6453
|
length: insert.length
|
|
6395
6454
|
}
|
|
6396
|
-
}, {
|
|
6397
|
-
F: __dxlog_file14,
|
|
6398
|
-
L: 164,
|
|
6399
|
-
S: void 0,
|
|
6400
|
-
C: (f, a) => f(...a)
|
|
6401
|
-
});
|
|
6455
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6402
6456
|
}
|
|
6403
6457
|
});
|
|
6404
6458
|
if (changes.length > 0) {
|
|
6405
|
-
|
|
6459
|
+
log10("modified,", {
|
|
6406
6460
|
changes
|
|
6407
|
-
}, {
|
|
6408
|
-
F: __dxlog_file14,
|
|
6409
|
-
L: 175,
|
|
6410
|
-
S: void 0,
|
|
6411
|
-
C: (f, a) => f(...a)
|
|
6412
|
-
});
|
|
6461
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6413
6462
|
return [
|
|
6414
6463
|
{
|
|
6415
6464
|
changes
|
|
6416
6465
|
}
|
|
6417
6466
|
];
|
|
6418
6467
|
} else if (cancel) {
|
|
6419
|
-
|
|
6420
|
-
F: __dxlog_file14,
|
|
6421
|
-
L: 178,
|
|
6422
|
-
S: void 0,
|
|
6423
|
-
C: (f, a) => f(...a)
|
|
6424
|
-
});
|
|
6468
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6425
6469
|
return [];
|
|
6426
6470
|
}
|
|
6427
6471
|
return tr;
|
|
@@ -6429,10 +6473,10 @@ var editor = () => [
|
|
|
6429
6473
|
];
|
|
6430
6474
|
|
|
6431
6475
|
// src/extensions/outliner/menu.ts
|
|
6432
|
-
import { EditorView as
|
|
6476
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6433
6477
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6434
6478
|
var menu = (options = {}) => [
|
|
6435
|
-
|
|
6479
|
+
ViewPlugin17.fromClass(class {
|
|
6436
6480
|
view;
|
|
6437
6481
|
tag;
|
|
6438
6482
|
rafId;
|
|
@@ -6494,7 +6538,7 @@ var menu = (options = {}) => [
|
|
|
6494
6538
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6495
6539
|
}
|
|
6496
6540
|
}),
|
|
6497
|
-
|
|
6541
|
+
EditorView25.theme({
|
|
6498
6542
|
".cm-popover-trigger": {
|
|
6499
6543
|
position: "fixed",
|
|
6500
6544
|
padding: "0",
|
|
@@ -6530,12 +6574,12 @@ var outliner = (_options = {}) => [
|
|
|
6530
6574
|
listPaddingLeft: 8
|
|
6531
6575
|
}),
|
|
6532
6576
|
// Researve space for menu.
|
|
6533
|
-
|
|
6534
|
-
class: "
|
|
6577
|
+
EditorView26.contentAttributes.of({
|
|
6578
|
+
class: "w-full !mr-[3rem]"
|
|
6535
6579
|
})
|
|
6536
6580
|
];
|
|
6537
6581
|
var decorations = () => [
|
|
6538
|
-
|
|
6582
|
+
ViewPlugin18.fromClass(class {
|
|
6539
6583
|
decorations = Decoration12.none;
|
|
6540
6584
|
constructor(view) {
|
|
6541
6585
|
this.updateDecorations(view.state, view);
|
|
@@ -6560,7 +6604,7 @@ var decorations = () => [
|
|
|
6560
6604
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6561
6605
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6562
6606
|
decorations2.push(Decoration12.line({
|
|
6563
|
-
class:
|
|
6607
|
+
class: mx6("cm-list-item", lineFrom.number === line.number && "cm-list-item-start", lineTo.number === line.number && "cm-list-item-end", isSelected && (hasFocus ? "cm-list-item-focused" : "cm-list-item-selected"))
|
|
6564
6608
|
}).range(line.from, line.from));
|
|
6565
6609
|
}
|
|
6566
6610
|
}
|
|
@@ -6570,7 +6614,7 @@ var decorations = () => [
|
|
|
6570
6614
|
decorations: (v) => v.decorations
|
|
6571
6615
|
}),
|
|
6572
6616
|
// Theme.
|
|
6573
|
-
|
|
6617
|
+
EditorView26.theme(Object.assign({
|
|
6574
6618
|
".cm-list-item": {
|
|
6575
6619
|
borderLeftWidth: "1px",
|
|
6576
6620
|
borderRightWidth: "1px",
|
|
@@ -6595,38 +6639,67 @@ var decorations = () => [
|
|
|
6595
6639
|
marginBottom: "2px"
|
|
6596
6640
|
},
|
|
6597
6641
|
".cm-list-item-focused": {
|
|
6598
|
-
borderColor: "var(--
|
|
6642
|
+
borderColor: "var(--color-neutral-focus-indicator)"
|
|
6599
6643
|
},
|
|
6600
6644
|
"&:focus-within .cm-list-item-selected": {
|
|
6601
|
-
borderColor: "var(--
|
|
6645
|
+
borderColor: "var(--color-separator)"
|
|
6602
6646
|
}
|
|
6603
6647
|
}))
|
|
6604
6648
|
];
|
|
6605
6649
|
|
|
6606
6650
|
// src/extensions/preview/preview.ts
|
|
6607
6651
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6608
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
|
|
6609
|
-
import { Decoration as Decoration13, EditorView as
|
|
6652
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
|
|
6653
|
+
import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6654
|
+
import { DXN, Entity } from "@dxos/echo";
|
|
6655
|
+
var labelResolvedEffect = StateEffect9.define();
|
|
6610
6656
|
var preview = (options = {}) => {
|
|
6657
|
+
const viewRef = {
|
|
6658
|
+
current: void 0
|
|
6659
|
+
};
|
|
6611
6660
|
return [
|
|
6612
6661
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6613
6662
|
// "Block decorations may not be specified via plugins".
|
|
6614
6663
|
StateField11.define({
|
|
6615
|
-
create: (state) => buildDecorations3(state, options),
|
|
6664
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6616
6665
|
update: (decorations2, tr) => {
|
|
6617
|
-
if (tr.docChanged) {
|
|
6618
|
-
return buildDecorations3(tr.state, options);
|
|
6666
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6667
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6619
6668
|
}
|
|
6620
6669
|
return decorations2.map(tr.changes);
|
|
6621
6670
|
},
|
|
6622
6671
|
provide: (field) => [
|
|
6623
|
-
|
|
6624
|
-
|
|
6672
|
+
EditorView27.decorations.from(field),
|
|
6673
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6625
6674
|
]
|
|
6675
|
+
}),
|
|
6676
|
+
ViewPlugin19.define((view) => {
|
|
6677
|
+
viewRef.current = view;
|
|
6678
|
+
return {
|
|
6679
|
+
destroy() {
|
|
6680
|
+
viewRef.current = void 0;
|
|
6681
|
+
}
|
|
6682
|
+
};
|
|
6626
6683
|
})
|
|
6627
6684
|
];
|
|
6628
6685
|
};
|
|
6629
|
-
var
|
|
6686
|
+
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6687
|
+
const dxn = DXN.tryParse(dxnStr);
|
|
6688
|
+
if (!dxn) {
|
|
6689
|
+
return;
|
|
6690
|
+
}
|
|
6691
|
+
const ref = db.makeRef(dxn);
|
|
6692
|
+
const target = ref.target;
|
|
6693
|
+
if (target) {
|
|
6694
|
+
return Entity.getLabel(target);
|
|
6695
|
+
}
|
|
6696
|
+
void ref.tryLoad().then(() => {
|
|
6697
|
+
viewRef.current?.dispatch({
|
|
6698
|
+
effects: labelResolvedEffect.of(void 0)
|
|
6699
|
+
});
|
|
6700
|
+
});
|
|
6701
|
+
};
|
|
6702
|
+
var buildDecorations3 = (state, options, viewRef) => {
|
|
6630
6703
|
const builder = new RangeSetBuilder6();
|
|
6631
6704
|
syntaxTree10(state).iterate({
|
|
6632
6705
|
enter: (node) => {
|
|
@@ -6638,8 +6711,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6638
6711
|
case "Link": {
|
|
6639
6712
|
const link = getLinkRef(state, node.node);
|
|
6640
6713
|
if (link) {
|
|
6714
|
+
const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : void 0;
|
|
6715
|
+
const displayLink = resolved ? {
|
|
6716
|
+
...link,
|
|
6717
|
+
label: resolved
|
|
6718
|
+
} : link;
|
|
6641
6719
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6642
|
-
widget: new PreviewInlineWidget(options,
|
|
6720
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6643
6721
|
side: 1
|
|
6644
6722
|
}));
|
|
6645
6723
|
}
|
|
@@ -6715,7 +6793,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6715
6793
|
}
|
|
6716
6794
|
toDOM(_view) {
|
|
6717
6795
|
const root = document.createElement("div");
|
|
6718
|
-
root.classList.add("cm-preview-block", "density-fine");
|
|
6796
|
+
root.classList.add("cm-preview-block", "dx-density-fine");
|
|
6719
6797
|
this._options.addBlockContainer?.({
|
|
6720
6798
|
link: this._link,
|
|
6721
6799
|
el: root
|
|
@@ -6731,7 +6809,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6731
6809
|
};
|
|
6732
6810
|
|
|
6733
6811
|
// src/extensions/replacer.ts
|
|
6734
|
-
import { EditorView as
|
|
6812
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6735
6813
|
var defaultReplacements = [
|
|
6736
6814
|
{
|
|
6737
6815
|
input: "--",
|
|
@@ -6794,7 +6872,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6794
6872
|
const sortedReplacements = [
|
|
6795
6873
|
...replacements
|
|
6796
6874
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6797
|
-
return
|
|
6875
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6798
6876
|
if (insert.length !== 1) {
|
|
6799
6877
|
return false;
|
|
6800
6878
|
}
|
|
@@ -6828,12 +6906,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6828
6906
|
});
|
|
6829
6907
|
};
|
|
6830
6908
|
|
|
6909
|
+
// src/extensions/snippets.ts
|
|
6910
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
6911
|
+
var defaultItems = [
|
|
6912
|
+
"hello world!",
|
|
6913
|
+
"this is a test.",
|
|
6914
|
+
"this is [DXOS](https://dxos.org)"
|
|
6915
|
+
];
|
|
6916
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
6917
|
+
let timer;
|
|
6918
|
+
let index = 0;
|
|
6919
|
+
return [
|
|
6920
|
+
keymap12.of([
|
|
6921
|
+
{
|
|
6922
|
+
// Reset.
|
|
6923
|
+
key: "alt-meta-'",
|
|
6924
|
+
run: () => {
|
|
6925
|
+
clearTimeout(timer);
|
|
6926
|
+
index = 0;
|
|
6927
|
+
return true;
|
|
6928
|
+
}
|
|
6929
|
+
},
|
|
6930
|
+
{
|
|
6931
|
+
// Next snippet.
|
|
6932
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
6933
|
+
key: "Shift-Meta-'",
|
|
6934
|
+
run: (view) => {
|
|
6935
|
+
clearTimeout(timer);
|
|
6936
|
+
const text = items[index++];
|
|
6937
|
+
if (index === items?.length) {
|
|
6938
|
+
index = 0;
|
|
6939
|
+
}
|
|
6940
|
+
let offset = 0;
|
|
6941
|
+
const insert = (delayMs = 0) => {
|
|
6942
|
+
timer = setTimeout(() => {
|
|
6943
|
+
const pos = view.state.selection.main.head;
|
|
6944
|
+
view.dispatch({
|
|
6945
|
+
changes: {
|
|
6946
|
+
from: pos,
|
|
6947
|
+
insert: text[offset++]
|
|
6948
|
+
},
|
|
6949
|
+
selection: {
|
|
6950
|
+
anchor: pos + 1
|
|
6951
|
+
}
|
|
6952
|
+
});
|
|
6953
|
+
if (offset < text.length) {
|
|
6954
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
6955
|
+
}
|
|
6956
|
+
}, delayMs);
|
|
6957
|
+
};
|
|
6958
|
+
insert();
|
|
6959
|
+
return true;
|
|
6960
|
+
}
|
|
6961
|
+
}
|
|
6962
|
+
])
|
|
6963
|
+
];
|
|
6964
|
+
};
|
|
6965
|
+
|
|
6831
6966
|
// src/extensions/submit.ts
|
|
6832
6967
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6833
|
-
import { keymap as
|
|
6968
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6834
6969
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6835
6970
|
return [
|
|
6836
|
-
Prec6.highest(
|
|
6971
|
+
Prec6.highest(keymap13.of([
|
|
6837
6972
|
{
|
|
6838
6973
|
key: "Enter",
|
|
6839
6974
|
preventDefault: true,
|
|
@@ -6878,6 +7013,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6878
7013
|
// src/extensions/tags/extended-markdown.ts
|
|
6879
7014
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6880
7015
|
import { parseMixed } from "@lezer/common";
|
|
7016
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6881
7017
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6882
7018
|
return [
|
|
6883
7019
|
createMarkdownExtensions({
|
|
@@ -6889,13 +7025,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6889
7025
|
{
|
|
6890
7026
|
name: "SetextHeading",
|
|
6891
7027
|
parse: () => false
|
|
6892
|
-
}
|
|
7028
|
+
},
|
|
7029
|
+
// Custom XML block parser that keeps registered tags as a single HTMLBlock
|
|
7030
|
+
// even when their content contains blank lines.
|
|
7031
|
+
...xmlBlockParsers(registry)
|
|
6893
7032
|
]
|
|
6894
7033
|
}
|
|
6895
7034
|
]
|
|
6896
7035
|
})
|
|
6897
7036
|
];
|
|
6898
7037
|
};
|
|
7038
|
+
var xmlBlockParsers = (registry) => {
|
|
7039
|
+
const customTags = Object.keys(registry ?? {});
|
|
7040
|
+
if (customTags.length === 0) {
|
|
7041
|
+
return [];
|
|
7042
|
+
}
|
|
7043
|
+
const tagPattern = customTags.map(escapeRegExpSource).join("|");
|
|
7044
|
+
const selfClosePattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/>\\s*$`);
|
|
7045
|
+
const openPattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/?>`);
|
|
7046
|
+
return [
|
|
7047
|
+
{
|
|
7048
|
+
name: "XMLBlock",
|
|
7049
|
+
before: "HTMLBlock",
|
|
7050
|
+
parse: (cx, line) => {
|
|
7051
|
+
const match = openPattern.exec(line.text);
|
|
7052
|
+
if (!match) {
|
|
7053
|
+
return false;
|
|
7054
|
+
}
|
|
7055
|
+
if (selfClosePattern.test(line.text)) {
|
|
7056
|
+
const end2 = cx.lineStart + line.text.length;
|
|
7057
|
+
cx.addElement(cx.elt("HTMLBlock", cx.lineStart, end2));
|
|
7058
|
+
cx.nextLine();
|
|
7059
|
+
return true;
|
|
7060
|
+
}
|
|
7061
|
+
if (match[0].trimEnd().endsWith("/>")) {
|
|
7062
|
+
return false;
|
|
7063
|
+
}
|
|
7064
|
+
const tagName = match[1];
|
|
7065
|
+
const closeTag = `</${tagName}>`;
|
|
7066
|
+
const start = cx.lineStart;
|
|
7067
|
+
if (line.text.includes(closeTag)) {
|
|
7068
|
+
cx.addElement(cx.elt("HTMLBlock", start, start + line.text.length));
|
|
7069
|
+
cx.nextLine();
|
|
7070
|
+
return true;
|
|
7071
|
+
}
|
|
7072
|
+
let end = cx.lineStart + line.text.length;
|
|
7073
|
+
while (cx.nextLine()) {
|
|
7074
|
+
end = cx.lineStart + line.text.length;
|
|
7075
|
+
if (line.text.includes(closeTag)) {
|
|
7076
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7077
|
+
cx.nextLine();
|
|
7078
|
+
return true;
|
|
7079
|
+
}
|
|
7080
|
+
}
|
|
7081
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7082
|
+
return true;
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
];
|
|
7086
|
+
};
|
|
6899
7087
|
var mixedParser = (registry) => {
|
|
6900
7088
|
const customTags = Object.keys(registry ?? {});
|
|
6901
7089
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6929,219 +7117,793 @@ var mixedParser = (registry) => {
|
|
|
6929
7117
|
});
|
|
6930
7118
|
};
|
|
6931
7119
|
|
|
6932
|
-
// src/extensions/tags/
|
|
6933
|
-
import { StateEffect as
|
|
6934
|
-
import { Decoration as Decoration14, EditorView as
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
var
|
|
6938
|
-
var
|
|
7120
|
+
// src/extensions/tags/fader.ts
|
|
7121
|
+
import { StateEffect as StateEffect10, StateField as StateField12 } from "@codemirror/state";
|
|
7122
|
+
import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
7123
|
+
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7124
|
+
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7125
|
+
var CLEANUP_INTERVAL = 1e3;
|
|
7126
|
+
var fader = (options = {}) => {
|
|
7127
|
+
const removalDelay = DEFAULT_REMOVAL_DELAY;
|
|
7128
|
+
const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;
|
|
7129
|
+
let lastCount = -1;
|
|
7130
|
+
const log12 = (expiries) => {
|
|
7131
|
+
if (expiries.length !== lastCount) {
|
|
7132
|
+
lastCount = expiries.length;
|
|
7133
|
+
}
|
|
7134
|
+
};
|
|
7135
|
+
const dequeue = StateEffect10.define();
|
|
7136
|
+
const fadeField = StateField12.define({
|
|
7137
|
+
create: () => ({
|
|
7138
|
+
decorations: Decoration14.none,
|
|
7139
|
+
expiries: [],
|
|
7140
|
+
batchStart: 0
|
|
7141
|
+
}),
|
|
7142
|
+
update: ({ decorations: decorations2, expiries, batchStart }, tr) => {
|
|
7143
|
+
for (const effect of tr.effects) {
|
|
7144
|
+
if (effect.is(dequeue)) {
|
|
7145
|
+
const now2 = effect.value;
|
|
7146
|
+
let removeCount = 0;
|
|
7147
|
+
while (removeCount < expiries.length && expiries[removeCount] <= now2) {
|
|
7148
|
+
removeCount++;
|
|
7149
|
+
}
|
|
7150
|
+
if (removeCount > 0) {
|
|
7151
|
+
expiries = expiries.slice(removeCount);
|
|
7152
|
+
let skipped = 0;
|
|
7153
|
+
decorations2 = decorations2.update({
|
|
7154
|
+
filter: () => {
|
|
7155
|
+
if (skipped < removeCount) {
|
|
7156
|
+
skipped++;
|
|
7157
|
+
return false;
|
|
7158
|
+
}
|
|
7159
|
+
return true;
|
|
7160
|
+
}
|
|
7161
|
+
});
|
|
7162
|
+
}
|
|
7163
|
+
}
|
|
7164
|
+
}
|
|
7165
|
+
if (!tr.docChanged) {
|
|
7166
|
+
log12(expiries);
|
|
7167
|
+
return {
|
|
7168
|
+
decorations: decorations2,
|
|
7169
|
+
expiries,
|
|
7170
|
+
batchStart
|
|
7171
|
+
};
|
|
7172
|
+
}
|
|
7173
|
+
let isReset = tr.state.doc.length === 0;
|
|
7174
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7175
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7176
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7177
|
+
isReset = true;
|
|
7178
|
+
}
|
|
7179
|
+
});
|
|
7180
|
+
}
|
|
7181
|
+
if (isReset) {
|
|
7182
|
+
log12([]);
|
|
7183
|
+
return {
|
|
7184
|
+
decorations: Decoration14.none,
|
|
7185
|
+
expiries: [],
|
|
7186
|
+
batchStart: 0
|
|
7187
|
+
};
|
|
7188
|
+
}
|
|
7189
|
+
const now = Date.now();
|
|
7190
|
+
const add = [];
|
|
7191
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
7192
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
7193
|
+
add.push({
|
|
7194
|
+
from: fromB,
|
|
7195
|
+
to: toB
|
|
7196
|
+
});
|
|
7197
|
+
}
|
|
7198
|
+
});
|
|
7199
|
+
if (add.length > 0) {
|
|
7200
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
7201
|
+
if (canCoalesce) {
|
|
7202
|
+
let lastFrom = -1;
|
|
7203
|
+
let lastTo = -1;
|
|
7204
|
+
decorations2.between(0, tr.state.doc.length, (from, to) => {
|
|
7205
|
+
lastFrom = from;
|
|
7206
|
+
lastTo = to;
|
|
7207
|
+
});
|
|
7208
|
+
if (lastFrom >= 0) {
|
|
7209
|
+
decorations2 = decorations2.update({
|
|
7210
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo)
|
|
7211
|
+
});
|
|
7212
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
7213
|
+
const mergedTo = add[add.length - 1].to;
|
|
7214
|
+
decorations2 = decorations2.update({
|
|
7215
|
+
add: [
|
|
7216
|
+
Decoration14.mark({
|
|
7217
|
+
class: "cm-fader"
|
|
7218
|
+
}).range(mergedFrom, mergedTo)
|
|
7219
|
+
]
|
|
7220
|
+
});
|
|
7221
|
+
expiries = [
|
|
7222
|
+
...expiries.slice(0, -1),
|
|
7223
|
+
now + removalDelay
|
|
7224
|
+
];
|
|
7225
|
+
}
|
|
7226
|
+
} else {
|
|
7227
|
+
batchStart = now;
|
|
7228
|
+
expiries = [
|
|
7229
|
+
...expiries,
|
|
7230
|
+
now + removalDelay
|
|
7231
|
+
];
|
|
7232
|
+
decorations2 = decorations2.update({
|
|
7233
|
+
add: add.map(({ from, to }) => Decoration14.mark({
|
|
7234
|
+
class: "cm-fader"
|
|
7235
|
+
}).range(from, to))
|
|
7236
|
+
});
|
|
7237
|
+
}
|
|
7238
|
+
}
|
|
7239
|
+
log12(expiries);
|
|
7240
|
+
return {
|
|
7241
|
+
decorations: decorations2,
|
|
7242
|
+
expiries,
|
|
7243
|
+
batchStart
|
|
7244
|
+
};
|
|
7245
|
+
},
|
|
7246
|
+
provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
|
|
7247
|
+
});
|
|
7248
|
+
const cleanup = ViewPlugin20.fromClass(class {
|
|
7249
|
+
view;
|
|
7250
|
+
#timer;
|
|
7251
|
+
constructor(view) {
|
|
7252
|
+
this.view = view;
|
|
7253
|
+
this.#schedule();
|
|
7254
|
+
}
|
|
7255
|
+
update() {
|
|
7256
|
+
this.#schedule();
|
|
7257
|
+
}
|
|
7258
|
+
#schedule() {
|
|
7259
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
7260
|
+
if (expiries.length === 0) {
|
|
7261
|
+
clearTimeout(this.#timer);
|
|
7262
|
+
this.#timer = void 0;
|
|
7263
|
+
return;
|
|
7264
|
+
}
|
|
7265
|
+
if (this.#timer !== void 0) {
|
|
7266
|
+
return;
|
|
7267
|
+
}
|
|
7268
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
7269
|
+
this.#timer = setTimeout(() => {
|
|
7270
|
+
this.#timer = void 0;
|
|
7271
|
+
this.view.dispatch({
|
|
7272
|
+
effects: dequeue.of(Date.now())
|
|
7273
|
+
});
|
|
7274
|
+
}, delay);
|
|
7275
|
+
}
|
|
7276
|
+
destroy() {
|
|
7277
|
+
clearTimeout(this.#timer);
|
|
7278
|
+
}
|
|
7279
|
+
});
|
|
6939
7280
|
return [
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
7281
|
+
fadeField,
|
|
7282
|
+
cleanup,
|
|
7283
|
+
EditorView29.theme({
|
|
7284
|
+
".cm-fader": {
|
|
7285
|
+
animation: "fader 1s ease-out forwards"
|
|
7286
|
+
},
|
|
7287
|
+
"@keyframes fader": {
|
|
7288
|
+
"0%": {
|
|
7289
|
+
textShadow: "0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)"
|
|
7290
|
+
},
|
|
7291
|
+
"100%": {}
|
|
7292
|
+
}
|
|
7293
|
+
})
|
|
7294
|
+
];
|
|
7295
|
+
};
|
|
7296
|
+
|
|
7297
|
+
// src/extensions/tags/typewriter.ts
|
|
7298
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7299
|
+
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7300
|
+
import { Domino as Domino3 } from "@dxos/ui";
|
|
7301
|
+
var typewriterBypass = Annotation3.define();
|
|
7302
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7303
|
+
var CURSOR_LINGER = 3e3;
|
|
7304
|
+
var FRAME_BUDGET_MS = 4;
|
|
7305
|
+
var CHARS_PER_FRAME = 5;
|
|
7306
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7307
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7308
|
+
var typewriter = (options = {}) => {
|
|
7309
|
+
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7310
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7311
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7312
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7313
|
+
const suppressAppend = StateEffect11.define();
|
|
7314
|
+
const insertChunk = StateEffect11.define();
|
|
7315
|
+
const bufferField = StateField13.define({
|
|
7316
|
+
create: () => ({
|
|
7317
|
+
text: "",
|
|
7318
|
+
head: 0,
|
|
7319
|
+
insertAt: 0
|
|
7320
|
+
}),
|
|
6948
7321
|
update: (value, tr) => {
|
|
7322
|
+
let { text, head, insertAt } = value;
|
|
6949
7323
|
for (const effect of tr.effects) {
|
|
6950
|
-
if (effect.is(
|
|
6951
|
-
|
|
7324
|
+
if (effect.is(suppressAppend)) {
|
|
7325
|
+
if (text.length === head) {
|
|
7326
|
+
insertAt = effect.value.from;
|
|
7327
|
+
}
|
|
7328
|
+
text += effect.value.text;
|
|
7329
|
+
}
|
|
7330
|
+
if (effect.is(insertChunk)) {
|
|
7331
|
+
head += effect.value.text.length;
|
|
7332
|
+
insertAt = effect.value.from + effect.value.text.length;
|
|
7333
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7334
|
+
text = text.slice(head);
|
|
7335
|
+
head = 0;
|
|
7336
|
+
}
|
|
6952
7337
|
}
|
|
6953
7338
|
}
|
|
6954
7339
|
if (tr.docChanged) {
|
|
6955
|
-
|
|
7340
|
+
let isReset = tr.state.doc.length === 0;
|
|
7341
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7342
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7343
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7344
|
+
isReset = true;
|
|
7345
|
+
}
|
|
7346
|
+
});
|
|
7347
|
+
}
|
|
7348
|
+
if (isReset) {
|
|
7349
|
+
return {
|
|
7350
|
+
text: "",
|
|
7351
|
+
head: 0,
|
|
7352
|
+
insertAt: 0
|
|
7353
|
+
};
|
|
7354
|
+
}
|
|
7355
|
+
if (!tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7356
|
+
insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));
|
|
7357
|
+
}
|
|
6956
7358
|
}
|
|
6957
|
-
return
|
|
7359
|
+
return {
|
|
7360
|
+
text,
|
|
7361
|
+
head,
|
|
7362
|
+
insertAt
|
|
7363
|
+
};
|
|
7364
|
+
}
|
|
7365
|
+
});
|
|
7366
|
+
const filter = EditorState3.transactionFilter.of((tr) => {
|
|
7367
|
+
if (!tr.docChanged) {
|
|
7368
|
+
return tr;
|
|
7369
|
+
}
|
|
7370
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7371
|
+
return tr;
|
|
7372
|
+
}
|
|
7373
|
+
let appendedText = "";
|
|
7374
|
+
let appendFrom = -1;
|
|
7375
|
+
let isAppendOnly = true;
|
|
7376
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {
|
|
7377
|
+
if (toA === tr.startState.doc.length && fromA === toA && inserted.length > 0) {
|
|
7378
|
+
appendedText += inserted.sliceString(0);
|
|
7379
|
+
if (appendFrom === -1) {
|
|
7380
|
+
appendFrom = fromA;
|
|
7381
|
+
}
|
|
7382
|
+
} else {
|
|
7383
|
+
isAppendOnly = false;
|
|
7384
|
+
}
|
|
7385
|
+
});
|
|
7386
|
+
if (!isAppendOnly || appendedText.length === 0) {
|
|
7387
|
+
return tr;
|
|
6958
7388
|
}
|
|
7389
|
+
return {
|
|
7390
|
+
changes: ChangeSet2.empty(tr.startState.doc.length),
|
|
7391
|
+
effects: suppressAppend.of({
|
|
7392
|
+
from: appendFrom,
|
|
7393
|
+
text: appendedText
|
|
7394
|
+
})
|
|
7395
|
+
};
|
|
6959
7396
|
});
|
|
6960
|
-
const
|
|
7397
|
+
const drainPlugin = ViewPlugin21.fromClass(class {
|
|
6961
7398
|
view;
|
|
6962
|
-
|
|
7399
|
+
_raf;
|
|
7400
|
+
_activeStreamTag = null;
|
|
6963
7401
|
constructor(view) {
|
|
6964
7402
|
this.view = view;
|
|
6965
7403
|
}
|
|
6966
7404
|
update(update2) {
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
7405
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7406
|
+
const pending = text.length - head;
|
|
7407
|
+
if (pending === 0) {
|
|
7408
|
+
this._activeStreamTag = null;
|
|
7409
|
+
}
|
|
7410
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7411
|
+
this._start();
|
|
6974
7412
|
}
|
|
6975
7413
|
}
|
|
7414
|
+
_start() {
|
|
7415
|
+
queueMicrotask(() => {
|
|
7416
|
+
this.view.dispatch({
|
|
7417
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7418
|
+
annotations: typewriterBypass.of(true)
|
|
7419
|
+
});
|
|
7420
|
+
});
|
|
7421
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7422
|
+
}
|
|
7423
|
+
_tick = () => {
|
|
7424
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7425
|
+
const pending = text.length - head;
|
|
7426
|
+
if (pending === 0) {
|
|
7427
|
+
this.view.dispatch({
|
|
7428
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7429
|
+
annotations: typewriterBypass.of(true)
|
|
7430
|
+
});
|
|
7431
|
+
this._raf = void 0;
|
|
7432
|
+
return;
|
|
7433
|
+
}
|
|
7434
|
+
if (pending > flushThreshold) {
|
|
7435
|
+
const chunk = text.slice(head);
|
|
7436
|
+
this._activeStreamTag = null;
|
|
7437
|
+
this.view.dispatch({
|
|
7438
|
+
changes: {
|
|
7439
|
+
from: insertAt,
|
|
7440
|
+
insert: chunk
|
|
7441
|
+
},
|
|
7442
|
+
effects: insertChunk.of({
|
|
7443
|
+
from: insertAt,
|
|
7444
|
+
text: chunk
|
|
7445
|
+
})
|
|
7446
|
+
});
|
|
7447
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7448
|
+
return;
|
|
7449
|
+
}
|
|
7450
|
+
const startTime = performance.now();
|
|
7451
|
+
let pos = head;
|
|
7452
|
+
let activeTag = this._activeStreamTag;
|
|
7453
|
+
let charsEmitted = 0;
|
|
7454
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7455
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7456
|
+
if (result.count === 0) {
|
|
7457
|
+
break;
|
|
7458
|
+
}
|
|
7459
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7460
|
+
break;
|
|
7461
|
+
}
|
|
7462
|
+
if (result.enterTag) {
|
|
7463
|
+
activeTag = result.enterTag;
|
|
7464
|
+
}
|
|
7465
|
+
if (result.exitTag) {
|
|
7466
|
+
activeTag = null;
|
|
7467
|
+
}
|
|
7468
|
+
pos += result.count;
|
|
7469
|
+
charsEmitted += result.count;
|
|
7470
|
+
}
|
|
7471
|
+
const totalCount = pos - head;
|
|
7472
|
+
if (totalCount > 0) {
|
|
7473
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7474
|
+
this._activeStreamTag = activeTag;
|
|
7475
|
+
this.view.dispatch({
|
|
7476
|
+
changes: {
|
|
7477
|
+
from: insertAt,
|
|
7478
|
+
insert: chunk
|
|
7479
|
+
},
|
|
7480
|
+
effects: insertChunk.of({
|
|
7481
|
+
from: insertAt,
|
|
7482
|
+
text: chunk
|
|
7483
|
+
})
|
|
7484
|
+
});
|
|
7485
|
+
}
|
|
7486
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7487
|
+
};
|
|
6976
7488
|
destroy() {
|
|
6977
|
-
|
|
7489
|
+
if (this._raf !== void 0) {
|
|
7490
|
+
cancelAnimationFrame(this._raf);
|
|
7491
|
+
}
|
|
6978
7492
|
}
|
|
6979
7493
|
});
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
7494
|
+
return [
|
|
7495
|
+
bufferField,
|
|
7496
|
+
filter,
|
|
7497
|
+
drainPlugin,
|
|
7498
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7499
|
+
].filter(Boolean);
|
|
7500
|
+
};
|
|
7501
|
+
var typewriterCursor = (bufferField) => {
|
|
7502
|
+
const hideCursor = StateEffect11.define();
|
|
7503
|
+
const visibilityField = StateField13.define({
|
|
7504
|
+
create: () => ({
|
|
7505
|
+
visible: false,
|
|
7506
|
+
insertAt: 0,
|
|
7507
|
+
lastNonWsAt: 0
|
|
7508
|
+
}),
|
|
7509
|
+
update: (value, tr) => {
|
|
7510
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7511
|
+
const pending = text.length - head;
|
|
7512
|
+
if (pending > 0) {
|
|
7513
|
+
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7514
|
+
if (tr.docChanged) {
|
|
7515
|
+
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
7516
|
+
const chunk = inserted.sliceString(0);
|
|
7517
|
+
if (chunk.trim().length > 0) {
|
|
7518
|
+
lastNonWsAt = _fromB + chunk.length;
|
|
7519
|
+
}
|
|
7520
|
+
});
|
|
7521
|
+
}
|
|
7522
|
+
return {
|
|
7523
|
+
visible: true,
|
|
7524
|
+
insertAt,
|
|
7525
|
+
lastNonWsAt
|
|
7526
|
+
};
|
|
6986
7527
|
}
|
|
6987
|
-
const
|
|
6988
|
-
|
|
6989
|
-
|
|
7528
|
+
for (const effect of tr.effects) {
|
|
7529
|
+
if (effect.is(hideCursor)) {
|
|
7530
|
+
return {
|
|
7531
|
+
...value,
|
|
7532
|
+
visible: false
|
|
7533
|
+
};
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
return value;
|
|
7537
|
+
}
|
|
7538
|
+
});
|
|
7539
|
+
const decorationField = StateField13.define({
|
|
7540
|
+
create: () => Decoration15.none,
|
|
7541
|
+
update: (_decorations, tr) => {
|
|
7542
|
+
const { visible, insertAt, lastNonWsAt } = tr.state.field(visibilityField);
|
|
7543
|
+
if (!visible) {
|
|
7544
|
+
return Decoration15.none;
|
|
7545
|
+
}
|
|
7546
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7547
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7548
|
+
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7549
|
+
return Decoration15.set([
|
|
7550
|
+
Decoration15.widget({
|
|
6990
7551
|
widget: new CursorWidget(),
|
|
6991
7552
|
side: 1
|
|
6992
|
-
}).range(
|
|
7553
|
+
}).range(pos)
|
|
6993
7554
|
]);
|
|
6994
7555
|
},
|
|
6995
|
-
provide: (
|
|
7556
|
+
provide: (field) => EditorView30.decorations.from(field)
|
|
7557
|
+
});
|
|
7558
|
+
const timerPlugin = ViewPlugin21.fromClass(class {
|
|
7559
|
+
view;
|
|
7560
|
+
_timer;
|
|
7561
|
+
constructor(view) {
|
|
7562
|
+
this.view = view;
|
|
7563
|
+
}
|
|
7564
|
+
update(update2) {
|
|
7565
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7566
|
+
const { visible } = update2.state.field(visibilityField);
|
|
7567
|
+
const pending = text.length - head;
|
|
7568
|
+
if (pending > 0) {
|
|
7569
|
+
clearTimeout(this._timer);
|
|
7570
|
+
this._timer = void 0;
|
|
7571
|
+
} else if (visible && this._timer === void 0) {
|
|
7572
|
+
this._timer = setTimeout(() => {
|
|
7573
|
+
this.view.dispatch({
|
|
7574
|
+
effects: hideCursor.of(null)
|
|
7575
|
+
});
|
|
7576
|
+
this._timer = void 0;
|
|
7577
|
+
}, CURSOR_LINGER);
|
|
7578
|
+
}
|
|
7579
|
+
}
|
|
7580
|
+
destroy() {
|
|
7581
|
+
clearTimeout(this._timer);
|
|
7582
|
+
}
|
|
6996
7583
|
});
|
|
6997
7584
|
return [
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7585
|
+
visibilityField,
|
|
7586
|
+
decorationField,
|
|
7587
|
+
timerPlugin
|
|
7001
7588
|
];
|
|
7002
7589
|
};
|
|
7003
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7590
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7591
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7592
|
+
// the blink animation isn't restarted on every transaction.
|
|
7593
|
+
eq(other) {
|
|
7594
|
+
return other instanceof _CursorWidget;
|
|
7595
|
+
}
|
|
7004
7596
|
toDOM() {
|
|
7005
|
-
const inner = Domino3.of("span").text("\
|
|
7006
|
-
animation: "blink
|
|
7597
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7598
|
+
animation: "blink 1s infinite",
|
|
7599
|
+
animationDelay: "250ms"
|
|
7007
7600
|
});
|
|
7008
7601
|
return Domino3.of("span").style({
|
|
7009
7602
|
opacity: "0.8"
|
|
7010
|
-
}).
|
|
7603
|
+
}).append(inner).root;
|
|
7011
7604
|
}
|
|
7012
7605
|
};
|
|
7013
|
-
var
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
|
|
7030
|
-
|
|
7031
|
-
|
|
7606
|
+
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7607
|
+
var TAG_NAME_PROBE = 64;
|
|
7608
|
+
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7609
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7610
|
+
if (start >= buffer.length) {
|
|
7611
|
+
return {
|
|
7612
|
+
count: 0
|
|
7613
|
+
};
|
|
7614
|
+
}
|
|
7615
|
+
if (activeStreamTag) {
|
|
7616
|
+
const closeTag = `</${activeStreamTag}>`;
|
|
7617
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7618
|
+
return {
|
|
7619
|
+
count: closeTag.length,
|
|
7620
|
+
exitTag: true
|
|
7621
|
+
};
|
|
7622
|
+
}
|
|
7623
|
+
if (buffer[start] === "<") {
|
|
7624
|
+
return {
|
|
7625
|
+
count: xmlElementLength(buffer, start)
|
|
7626
|
+
};
|
|
7627
|
+
}
|
|
7628
|
+
return {
|
|
7629
|
+
count: 1
|
|
7630
|
+
};
|
|
7631
|
+
}
|
|
7632
|
+
const ch = buffer[start];
|
|
7633
|
+
if (ch === "<") {
|
|
7634
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7635
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7636
|
+
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7637
|
+
const close = buffer.indexOf(">", start);
|
|
7638
|
+
if (close === -1) {
|
|
7639
|
+
return {
|
|
7640
|
+
count: 0
|
|
7641
|
+
};
|
|
7032
7642
|
}
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7036
|
-
|
|
7037
|
-
isReset = true;
|
|
7038
|
-
}
|
|
7039
|
-
});
|
|
7643
|
+
if (buffer[close - 1] === "/") {
|
|
7644
|
+
return {
|
|
7645
|
+
count: close + 1 - start
|
|
7646
|
+
};
|
|
7040
7647
|
}
|
|
7041
|
-
|
|
7042
|
-
|
|
7648
|
+
return {
|
|
7649
|
+
count: close + 1 - start,
|
|
7650
|
+
enterTag: nameMatch[1]
|
|
7651
|
+
};
|
|
7652
|
+
}
|
|
7653
|
+
return {
|
|
7654
|
+
count: xmlElementLength(buffer, start)
|
|
7655
|
+
};
|
|
7656
|
+
}
|
|
7657
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7658
|
+
return {
|
|
7659
|
+
count: linkLength(buffer, start, start + 1)
|
|
7660
|
+
};
|
|
7661
|
+
}
|
|
7662
|
+
if (ch === "[") {
|
|
7663
|
+
return {
|
|
7664
|
+
count: linkLength(buffer, start, start)
|
|
7665
|
+
};
|
|
7666
|
+
}
|
|
7667
|
+
return {
|
|
7668
|
+
count: 1
|
|
7669
|
+
};
|
|
7670
|
+
};
|
|
7671
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7672
|
+
const close = buffer.indexOf(">", start);
|
|
7673
|
+
if (close === -1) {
|
|
7674
|
+
return 0;
|
|
7675
|
+
}
|
|
7676
|
+
if (buffer[close - 1] === "/") {
|
|
7677
|
+
return close + 1 - start;
|
|
7678
|
+
}
|
|
7679
|
+
if (buffer[start + 1] === "/") {
|
|
7680
|
+
return close + 1 - start;
|
|
7681
|
+
}
|
|
7682
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7683
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7684
|
+
if (!nameMatch) {
|
|
7685
|
+
return 1;
|
|
7686
|
+
}
|
|
7687
|
+
const tagName = nameMatch[1];
|
|
7688
|
+
let depth = 0;
|
|
7689
|
+
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7690
|
+
tagPattern.lastIndex = start;
|
|
7691
|
+
let match;
|
|
7692
|
+
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7693
|
+
const isSelfClosing = match[0].endsWith("/>");
|
|
7694
|
+
const isClosing = match[1] === "/";
|
|
7695
|
+
if (isSelfClosing) {
|
|
7696
|
+
if (depth === 0) {
|
|
7697
|
+
return match.index + match[0].length - start;
|
|
7698
|
+
}
|
|
7699
|
+
} else if (isClosing) {
|
|
7700
|
+
depth--;
|
|
7701
|
+
if (depth === 0) {
|
|
7702
|
+
return match.index + match[0].length - start;
|
|
7043
7703
|
}
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7704
|
+
} else {
|
|
7705
|
+
depth++;
|
|
7706
|
+
}
|
|
7707
|
+
}
|
|
7708
|
+
return 0;
|
|
7709
|
+
};
|
|
7710
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7711
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7712
|
+
if (bracketClose === -1) {
|
|
7713
|
+
return 0;
|
|
7714
|
+
}
|
|
7715
|
+
if (bracketClose + 1 >= buffer.length) {
|
|
7716
|
+
return 0;
|
|
7717
|
+
}
|
|
7718
|
+
if (buffer[bracketClose + 1] !== "(") {
|
|
7719
|
+
return 1;
|
|
7720
|
+
}
|
|
7721
|
+
const parenClose = buffer.indexOf(")", bracketClose + 2);
|
|
7722
|
+
if (parenClose === -1) {
|
|
7723
|
+
return 0;
|
|
7724
|
+
}
|
|
7725
|
+
return parenClose + 1 - start;
|
|
7726
|
+
};
|
|
7727
|
+
|
|
7728
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7729
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7730
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7731
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7732
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7733
|
+
class: lineClass
|
|
7734
|
+
}) : void 0;
|
|
7735
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7736
|
+
class: contentClass
|
|
7737
|
+
}) : void 0;
|
|
7738
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7739
|
+
const buildDecorations5 = (view) => {
|
|
7740
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7741
|
+
if (!text.includes(`<${tag}`)) {
|
|
7742
|
+
return Decoration16.none;
|
|
7743
|
+
}
|
|
7744
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7745
|
+
const ranges = [];
|
|
7746
|
+
tree.iterate({
|
|
7747
|
+
enter: (node) => {
|
|
7748
|
+
if (node.type.name !== "Element") {
|
|
7047
7749
|
return;
|
|
7048
7750
|
}
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7751
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7752
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7753
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7754
|
+
if (!openTag || !tagNameNode) {
|
|
7755
|
+
return;
|
|
7053
7756
|
}
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7757
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7758
|
+
return;
|
|
7759
|
+
}
|
|
7760
|
+
const contentFrom = openTag.to;
|
|
7761
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7762
|
+
if (hideDecoration) {
|
|
7763
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7764
|
+
if (closeTag) {
|
|
7765
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7766
|
+
}
|
|
7767
|
+
}
|
|
7768
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7769
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7770
|
+
}
|
|
7771
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7772
|
+
let pos = contentFrom;
|
|
7773
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7774
|
+
const line = view.state.doc.lineAt(pos);
|
|
7775
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7776
|
+
if (line.to >= contentTo) {
|
|
7777
|
+
break;
|
|
7778
|
+
}
|
|
7779
|
+
pos = line.to + 1;
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
7782
|
+
}
|
|
7783
|
+
});
|
|
7784
|
+
return Decoration16.set(ranges, true);
|
|
7785
|
+
};
|
|
7786
|
+
return ViewPlugin22.fromClass(class {
|
|
7787
|
+
decorations;
|
|
7065
7788
|
constructor(view) {
|
|
7066
|
-
this.
|
|
7789
|
+
this.decorations = buildDecorations5(view);
|
|
7067
7790
|
}
|
|
7068
7791
|
update(update2) {
|
|
7069
|
-
if (
|
|
7070
|
-
|
|
7792
|
+
if (update2.docChanged) {
|
|
7793
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7071
7794
|
}
|
|
7072
|
-
|
|
7073
|
-
|
|
7795
|
+
}
|
|
7796
|
+
}, {
|
|
7797
|
+
decorations: (instance) => instance.decorations
|
|
7798
|
+
});
|
|
7799
|
+
};
|
|
7800
|
+
|
|
7801
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7802
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7803
|
+
import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
|
|
7804
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7805
|
+
"OpenTag",
|
|
7806
|
+
"CloseTag",
|
|
7807
|
+
"SelfClosingTag",
|
|
7808
|
+
"MismatchedCloseTag"
|
|
7809
|
+
]);
|
|
7810
|
+
var xmlElementMark = Decoration17.mark({
|
|
7811
|
+
class: "cm-xml-element"
|
|
7812
|
+
});
|
|
7813
|
+
var xmlTagMark = Decoration17.mark({
|
|
7814
|
+
class: "cm-xml-tag"
|
|
7815
|
+
});
|
|
7816
|
+
var xmlContentMark = Decoration17.mark({
|
|
7817
|
+
class: "cm-xml-content"
|
|
7818
|
+
});
|
|
7819
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7820
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7821
|
+
const buildDecorations5 = (view) => {
|
|
7822
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7823
|
+
if (!text.includes("<")) {
|
|
7824
|
+
return Decoration17.none;
|
|
7825
|
+
}
|
|
7826
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7827
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7828
|
+
const ranges = [];
|
|
7829
|
+
tree.iterate({
|
|
7830
|
+
enter: (node) => {
|
|
7831
|
+
const name = node.type.name;
|
|
7832
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
7833
|
+
if (skipSet) {
|
|
7834
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
7835
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7836
|
+
return false;
|
|
7837
|
+
}
|
|
7838
|
+
}
|
|
7839
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7840
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7074
7841
|
return;
|
|
7075
7842
|
}
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7843
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
7844
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7845
|
+
return;
|
|
7846
|
+
}
|
|
7847
|
+
if (name === "Element" && node.from < node.to) {
|
|
7848
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7849
|
+
if (openTag && skipSet) {
|
|
7850
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
7851
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7852
|
+
return false;
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7856
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7857
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
7858
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
7859
|
+
}
|
|
7079
7860
|
}
|
|
7080
|
-
const totalDelay = FADE_IN_DURATION + removalDelay;
|
|
7081
|
-
const id = setTimeout(() => {
|
|
7082
|
-
this.view.dispatch({
|
|
7083
|
-
effects: removeDecoration.of({
|
|
7084
|
-
from: fromB,
|
|
7085
|
-
to: toB
|
|
7086
|
-
})
|
|
7087
|
-
});
|
|
7088
|
-
this._timers.delete(key);
|
|
7089
|
-
}, totalDelay);
|
|
7090
|
-
this._timers.set(key, id);
|
|
7091
|
-
});
|
|
7092
|
-
}
|
|
7093
|
-
destroy() {
|
|
7094
|
-
for (const id of this._timers.values()) {
|
|
7095
|
-
clearTimeout(id);
|
|
7096
7861
|
}
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
}
|
|
7862
|
+
});
|
|
7863
|
+
return Decoration17.set(ranges, true);
|
|
7864
|
+
};
|
|
7100
7865
|
return [
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
},
|
|
7110
|
-
"@keyframes fade-in": {
|
|
7111
|
-
"0%": {
|
|
7112
|
-
opacity: "0"
|
|
7113
|
-
},
|
|
7114
|
-
"80%": {
|
|
7115
|
-
opacity: "1"
|
|
7116
|
-
},
|
|
7117
|
-
"100%": {
|
|
7118
|
-
opacity: "0.8"
|
|
7866
|
+
ViewPlugin23.fromClass(class {
|
|
7867
|
+
decorations;
|
|
7868
|
+
constructor(view) {
|
|
7869
|
+
this.decorations = buildDecorations5(view);
|
|
7870
|
+
}
|
|
7871
|
+
update(update2) {
|
|
7872
|
+
if (update2.docChanged) {
|
|
7873
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7119
7874
|
}
|
|
7120
7875
|
}
|
|
7876
|
+
}, {
|
|
7877
|
+
decorations: (instance) => instance.decorations
|
|
7878
|
+
}),
|
|
7879
|
+
EditorView31.baseTheme({
|
|
7880
|
+
".cm-xml-element": {
|
|
7881
|
+
backgroundColor: "var(--color-active-surface)",
|
|
7882
|
+
borderRadius: "0.25rem",
|
|
7883
|
+
padding: "0.25rem"
|
|
7884
|
+
},
|
|
7885
|
+
".cm-xml-tag": {
|
|
7886
|
+
color: "var(--color-blue-500)",
|
|
7887
|
+
fontFamily: "var(--font-mono)"
|
|
7888
|
+
},
|
|
7889
|
+
".cm-xml-content": {}
|
|
7121
7890
|
})
|
|
7122
7891
|
];
|
|
7123
7892
|
};
|
|
7124
7893
|
|
|
7125
7894
|
// src/extensions/tags/xml-tags.ts
|
|
7126
7895
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7127
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7128
|
-
import { Decoration as
|
|
7896
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
|
|
7897
|
+
import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7129
7898
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7130
|
-
import { log as
|
|
7899
|
+
import { log as log11 } from "@dxos/log";
|
|
7900
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7131
7901
|
|
|
7132
7902
|
// src/extensions/tags/xml-util.ts
|
|
7133
7903
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7134
|
-
var
|
|
7904
|
+
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7135
7905
|
var nodeToJson = (state, node) => {
|
|
7136
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7137
|
-
F: __dxlog_file15,
|
|
7138
|
-
L: 18,
|
|
7139
|
-
S: void 0,
|
|
7140
|
-
A: [
|
|
7141
|
-
"node.type.name === 'Element'",
|
|
7142
|
-
"'Node is not an Element'"
|
|
7143
|
-
]
|
|
7144
|
-
});
|
|
7906
|
+
invariant6(node.type.name === "Element", "Node is not an Element", { "~LogMeta": "~LogMeta", F: __dxlog_file16, L: 8, S: void 0, A: ["node.type.name === 'Element'", "'Node is not an Element'"] });
|
|
7145
7907
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7146
7908
|
if (openTag) {
|
|
7147
7909
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7173,13 +7935,23 @@ var nodeToJson = (state, node) => {
|
|
|
7173
7935
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7174
7936
|
const children = [];
|
|
7175
7937
|
let child = node.node.firstChild;
|
|
7938
|
+
const appendText = (raw) => {
|
|
7939
|
+
if (raw.length === 0) {
|
|
7940
|
+
return;
|
|
7941
|
+
}
|
|
7942
|
+
const last = children[children.length - 1];
|
|
7943
|
+
if (typeof last === "string") {
|
|
7944
|
+
children[children.length - 1] = last + raw;
|
|
7945
|
+
} else {
|
|
7946
|
+
children.push(raw);
|
|
7947
|
+
}
|
|
7948
|
+
};
|
|
7176
7949
|
while (child) {
|
|
7177
7950
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7178
7951
|
if (child.type.name === "Text") {
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
}
|
|
7952
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
7953
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
7954
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7183
7955
|
} else if (child.type.name === "Element") {
|
|
7184
7956
|
const data = nodeToJson(state, child);
|
|
7185
7957
|
if (data) {
|
|
@@ -7189,26 +7961,63 @@ var nodeToJson = (state, node) => {
|
|
|
7189
7961
|
}
|
|
7190
7962
|
child = child.nextSibling;
|
|
7191
7963
|
}
|
|
7964
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7965
|
+
children[0] = children[0].trimStart();
|
|
7966
|
+
}
|
|
7192
7967
|
if (children.length > 0) {
|
|
7193
|
-
|
|
7968
|
+
const lastIndex = children.length - 1;
|
|
7969
|
+
const last = children[lastIndex];
|
|
7970
|
+
if (typeof last === "string") {
|
|
7971
|
+
children[lastIndex] = last.trimEnd();
|
|
7972
|
+
}
|
|
7973
|
+
}
|
|
7974
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
7975
|
+
if (trimmed.length > 0) {
|
|
7976
|
+
tag.children = trimmed;
|
|
7194
7977
|
}
|
|
7195
7978
|
}
|
|
7196
7979
|
return tag;
|
|
7197
7980
|
}
|
|
7198
7981
|
};
|
|
7982
|
+
var XML_NAMED_ENTITIES = {
|
|
7983
|
+
"<": "<",
|
|
7984
|
+
">": ">",
|
|
7985
|
+
"&": "&",
|
|
7986
|
+
""": '"',
|
|
7987
|
+
"'": "'"
|
|
7988
|
+
};
|
|
7989
|
+
var decodeXmlEntity = (raw) => {
|
|
7990
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
7991
|
+
if (named !== void 0) {
|
|
7992
|
+
return named;
|
|
7993
|
+
}
|
|
7994
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
7995
|
+
if (numeric) {
|
|
7996
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
7997
|
+
if (Number.isFinite(code)) {
|
|
7998
|
+
try {
|
|
7999
|
+
return String.fromCodePoint(code);
|
|
8000
|
+
} catch {
|
|
8001
|
+
}
|
|
8002
|
+
}
|
|
8003
|
+
}
|
|
8004
|
+
return raw;
|
|
8005
|
+
};
|
|
7199
8006
|
|
|
7200
8007
|
// src/extensions/tags/xml-tags.ts
|
|
7201
|
-
var
|
|
7202
|
-
var navigatePreviousEffect =
|
|
7203
|
-
var navigateNextEffect =
|
|
8008
|
+
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
8009
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8010
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7204
8011
|
var getXmlTextChild = (children) => {
|
|
7205
8012
|
const child = children?.[0];
|
|
7206
8013
|
return typeof child === "string" ? child : null;
|
|
7207
8014
|
};
|
|
7208
|
-
var
|
|
7209
|
-
var
|
|
7210
|
-
var
|
|
7211
|
-
var
|
|
8015
|
+
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
8016
|
+
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8017
|
+
var xmlTagContextEffect = StateEffect12.define();
|
|
8018
|
+
var xmlTagResetEffect = StateEffect12.define();
|
|
8019
|
+
var xmlTagUpdateEffect = StateEffect12.define();
|
|
8020
|
+
var widgetContextStateField = StateField14.define({
|
|
7212
8021
|
create: () => void 0,
|
|
7213
8022
|
update: (value, tr) => {
|
|
7214
8023
|
for (const effect of tr.effects) {
|
|
@@ -7219,7 +8028,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7219
8028
|
return value;
|
|
7220
8029
|
}
|
|
7221
8030
|
});
|
|
7222
|
-
var widgetStateMapStateField =
|
|
8031
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7223
8032
|
create: () => ({}),
|
|
7224
8033
|
update: (map, tr) => {
|
|
7225
8034
|
for (const effect of tr.effects) {
|
|
@@ -7228,15 +8037,10 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7228
8037
|
}
|
|
7229
8038
|
if (effect.is(xmlTagUpdateEffect)) {
|
|
7230
8039
|
const { id, value } = effect.value;
|
|
7231
|
-
|
|
8040
|
+
log11("widget updated", {
|
|
7232
8041
|
id,
|
|
7233
8042
|
value
|
|
7234
|
-
}, {
|
|
7235
|
-
F: __dxlog_file16,
|
|
7236
|
-
L: 153,
|
|
7237
|
-
S: void 0,
|
|
7238
|
-
C: (f, a) => f(...a)
|
|
7239
|
-
});
|
|
8043
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7240
8044
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7241
8045
|
return {
|
|
7242
8046
|
...map,
|
|
@@ -7263,15 +8067,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7263
8067
|
const widgets = /* @__PURE__ */ new Map();
|
|
7264
8068
|
const notifier = {
|
|
7265
8069
|
mounted: (state) => {
|
|
7266
|
-
|
|
8070
|
+
log11("widget mounted", {
|
|
7267
8071
|
id: state.id,
|
|
7268
8072
|
tag: state.props._tag
|
|
7269
|
-
}, {
|
|
7270
|
-
F: __dxlog_file16,
|
|
7271
|
-
L: 206,
|
|
7272
|
-
S: void 0,
|
|
7273
|
-
C: (f, a) => f(...a)
|
|
7274
|
-
});
|
|
8073
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7275
8074
|
widgets.set(state.id, state);
|
|
7276
8075
|
setWidgets?.([
|
|
7277
8076
|
...widgets.values()
|
|
@@ -7279,15 +8078,10 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7279
8078
|
},
|
|
7280
8079
|
unmounted: (id) => {
|
|
7281
8080
|
const state = widgets.get(id);
|
|
7282
|
-
|
|
8081
|
+
log11("widget unmounted", {
|
|
7283
8082
|
id,
|
|
7284
8083
|
tag: state?.props._tag
|
|
7285
|
-
}, {
|
|
7286
|
-
F: __dxlog_file16,
|
|
7287
|
-
L: 212,
|
|
7288
|
-
S: void 0,
|
|
7289
|
-
C: (f, a) => f(...a)
|
|
7290
|
-
});
|
|
8084
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7291
8085
|
widgets.delete(id);
|
|
7292
8086
|
setWidgets?.([
|
|
7293
8087
|
...widgets.values()
|
|
@@ -7296,7 +8090,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7296
8090
|
};
|
|
7297
8091
|
return notifier;
|
|
7298
8092
|
};
|
|
7299
|
-
var keyHandlers =
|
|
8093
|
+
var keyHandlers = keymap14.of([
|
|
7300
8094
|
{
|
|
7301
8095
|
key: "Mod-ArrowUp",
|
|
7302
8096
|
run: (view) => {
|
|
@@ -7317,7 +8111,7 @@ var keyHandlers = keymap13.of([
|
|
|
7317
8111
|
}
|
|
7318
8112
|
]);
|
|
7319
8113
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7320
|
-
return
|
|
8114
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7321
8115
|
update2.transactions.forEach((transaction) => {
|
|
7322
8116
|
for (const effect of transaction.effects) {
|
|
7323
8117
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7345,11 +8139,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7345
8139
|
anchor: line.from,
|
|
7346
8140
|
head: line.from
|
|
7347
8141
|
},
|
|
7348
|
-
effects:
|
|
7349
|
-
line: line.number,
|
|
7350
|
-
|
|
7351
|
-
offset: -16
|
|
7352
|
-
}
|
|
8142
|
+
effects: scrollerLineEffect.of({
|
|
8143
|
+
line: line.number - 1,
|
|
8144
|
+
offset: -16
|
|
7353
8145
|
})
|
|
7354
8146
|
});
|
|
7355
8147
|
continue;
|
|
@@ -7380,11 +8172,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7380
8172
|
anchor: line.to,
|
|
7381
8173
|
head: line.to
|
|
7382
8174
|
},
|
|
7383
|
-
effects:
|
|
7384
|
-
line: line.number,
|
|
7385
|
-
|
|
7386
|
-
offset: -16
|
|
7387
|
-
}
|
|
8175
|
+
effects: scrollerLineEffect.of({
|
|
8176
|
+
line: line.number - 1,
|
|
8177
|
+
offset: -16
|
|
7388
8178
|
})
|
|
7389
8179
|
});
|
|
7390
8180
|
} else {
|
|
@@ -7394,11 +8184,9 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7394
8184
|
anchor: line.to,
|
|
7395
8185
|
head: line.to
|
|
7396
8186
|
},
|
|
7397
|
-
effects:
|
|
7398
|
-
line: line.number,
|
|
7399
|
-
|
|
7400
|
-
position: "end"
|
|
7401
|
-
}
|
|
8187
|
+
effects: scrollerLineEffect.of({
|
|
8188
|
+
line: line.number - 1,
|
|
8189
|
+
position: "end"
|
|
7402
8190
|
})
|
|
7403
8191
|
});
|
|
7404
8192
|
}
|
|
@@ -7408,7 +8196,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7408
8196
|
});
|
|
7409
8197
|
});
|
|
7410
8198
|
};
|
|
7411
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8199
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7412
8200
|
update(update2) {
|
|
7413
8201
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7414
8202
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7435,19 +8223,25 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7435
8223
|
}
|
|
7436
8224
|
}
|
|
7437
8225
|
});
|
|
7438
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8226
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7439
8227
|
create: (state) => {
|
|
7440
8228
|
return buildDecorations4(state, {
|
|
7441
8229
|
from: 0,
|
|
7442
8230
|
to: state.doc.length
|
|
7443
8231
|
}, registry, notifier);
|
|
7444
8232
|
},
|
|
7445
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8233
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7446
8234
|
for (const effect of tr.effects) {
|
|
7447
8235
|
if (effect.is(xmlTagResetEffect)) {
|
|
8236
|
+
if (tr.docChanged) {
|
|
8237
|
+
return buildDecorations4(tr.state, {
|
|
8238
|
+
from: 0,
|
|
8239
|
+
to: tr.state.doc.length
|
|
8240
|
+
}, registry, notifier);
|
|
8241
|
+
}
|
|
7448
8242
|
return {
|
|
7449
8243
|
from: 0,
|
|
7450
|
-
decorations:
|
|
8244
|
+
decorations: Decoration18.none
|
|
7451
8245
|
};
|
|
7452
8246
|
}
|
|
7453
8247
|
}
|
|
@@ -7455,27 +8249,26 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7455
8249
|
const { state } = tr;
|
|
7456
8250
|
const reset = tr.changes.touchesRange(0, from);
|
|
7457
8251
|
if (reset) {
|
|
7458
|
-
|
|
8252
|
+
log11("document reset", {
|
|
7459
8253
|
from,
|
|
7460
8254
|
to: state.doc.length
|
|
7461
|
-
}, {
|
|
7462
|
-
F: __dxlog_file16,
|
|
7463
|
-
L: 371,
|
|
7464
|
-
S: void 0,
|
|
7465
|
-
C: (f, a) => f(...a)
|
|
7466
|
-
});
|
|
8255
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7467
8256
|
return buildDecorations4(state, {
|
|
7468
8257
|
from: 0,
|
|
7469
8258
|
to: state.doc.length
|
|
7470
8259
|
}, registry, notifier);
|
|
7471
8260
|
} else {
|
|
8261
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7472
8262
|
const result = buildDecorations4(state, {
|
|
7473
|
-
from,
|
|
8263
|
+
from: rebuildFrom,
|
|
7474
8264
|
to: state.doc.length
|
|
7475
8265
|
}, registry, notifier);
|
|
7476
8266
|
return {
|
|
7477
8267
|
from: result.from,
|
|
8268
|
+
streamingFrom: result.streamingFrom,
|
|
7478
8269
|
decorations: decorations2.update({
|
|
8270
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8271
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7479
8272
|
add: decorationSetToArray(result.decorations)
|
|
7480
8273
|
})
|
|
7481
8274
|
};
|
|
@@ -7483,12 +8276,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7483
8276
|
}
|
|
7484
8277
|
return {
|
|
7485
8278
|
from,
|
|
8279
|
+
streamingFrom,
|
|
7486
8280
|
decorations: decorations2
|
|
7487
8281
|
};
|
|
7488
8282
|
},
|
|
7489
8283
|
provide: (field) => [
|
|
7490
|
-
|
|
7491
|
-
|
|
8284
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8285
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7492
8286
|
]
|
|
7493
8287
|
});
|
|
7494
8288
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7499,10 +8293,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7499
8293
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7500
8294
|
return {
|
|
7501
8295
|
from: range.from,
|
|
7502
|
-
decorations:
|
|
8296
|
+
decorations: Decoration18.none
|
|
7503
8297
|
};
|
|
7504
8298
|
}
|
|
7505
8299
|
let last = range.from;
|
|
8300
|
+
let streamingFrom;
|
|
7506
8301
|
tree.iterate({
|
|
7507
8302
|
from: range.from,
|
|
7508
8303
|
to: range.to,
|
|
@@ -7515,21 +8310,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7515
8310
|
if (args) {
|
|
7516
8311
|
const def = registry[args._tag];
|
|
7517
8312
|
if (def) {
|
|
8313
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8314
|
+
return false;
|
|
8315
|
+
}
|
|
7518
8316
|
const { block, factory, Component } = def;
|
|
7519
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7520
8317
|
const nodeRange = {
|
|
7521
8318
|
from: node.node.from,
|
|
7522
8319
|
to: node.node.to
|
|
7523
8320
|
};
|
|
8321
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8322
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7524
8323
|
const props = {
|
|
7525
|
-
|
|
8324
|
+
id: widgetId,
|
|
7526
8325
|
range: nodeRange,
|
|
8326
|
+
context,
|
|
7527
8327
|
...args,
|
|
7528
8328
|
...widgetState
|
|
7529
8329
|
};
|
|
7530
|
-
const widget = factory ? factory(props) : Component ?
|
|
8330
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7531
8331
|
if (widget) {
|
|
7532
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8332
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7533
8333
|
widget,
|
|
7534
8334
|
block,
|
|
7535
8335
|
atomic: true,
|
|
@@ -7541,20 +8341,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7541
8341
|
}
|
|
7542
8342
|
}
|
|
7543
8343
|
} catch (err) {
|
|
7544
|
-
|
|
7545
|
-
F: __dxlog_file16,
|
|
7546
|
-
L: 456,
|
|
7547
|
-
S: void 0,
|
|
7548
|
-
C: (f, a) => f(...a)
|
|
7549
|
-
});
|
|
8344
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7550
8345
|
}
|
|
7551
8346
|
return false;
|
|
7552
8347
|
}
|
|
7553
8348
|
}
|
|
7554
8349
|
}
|
|
7555
8350
|
});
|
|
8351
|
+
const streamingTagNames = Object.entries(registry).filter(([, def]) => def.streaming).map(([name]) => name).sort((a, b) => b.length - a.length);
|
|
8352
|
+
if (streamingTagNames.length > 0) {
|
|
8353
|
+
const tailText = state.sliceDoc(range.from, range.to);
|
|
8354
|
+
const streamingPattern = streamingTagNames.map(escapeRegExpSource3).join("|");
|
|
8355
|
+
const tagPattern = new RegExp(`<(${streamingPattern})(\\s[^>]*)?>`, "g");
|
|
8356
|
+
let match;
|
|
8357
|
+
while ((match = tagPattern.exec(tailText)) !== null) {
|
|
8358
|
+
const tagName = match[1];
|
|
8359
|
+
const closeTag = `</${tagName}>`;
|
|
8360
|
+
const afterOpen = match.index + match[0].length;
|
|
8361
|
+
if (tailText.indexOf(closeTag, afterOpen) === -1) {
|
|
8362
|
+
const absoluteFrom = range.from + match.index;
|
|
8363
|
+
const contentFrom = range.from + afterOpen;
|
|
8364
|
+
const innerText = state.sliceDoc(contentFrom, range.to).trim();
|
|
8365
|
+
const def = registry[tagName];
|
|
8366
|
+
const props = {
|
|
8367
|
+
_tag: tagName,
|
|
8368
|
+
context,
|
|
8369
|
+
range: {
|
|
8370
|
+
from: absoluteFrom,
|
|
8371
|
+
to: range.to
|
|
8372
|
+
},
|
|
8373
|
+
children: innerText ? [
|
|
8374
|
+
innerText
|
|
8375
|
+
] : void 0
|
|
8376
|
+
};
|
|
8377
|
+
const attrPattern = /(\w+)="([^"]*)"/g;
|
|
8378
|
+
let attrMatch;
|
|
8379
|
+
while ((attrMatch = attrPattern.exec(match[0])) !== null) {
|
|
8380
|
+
props[attrMatch[1]] = attrMatch[2];
|
|
8381
|
+
}
|
|
8382
|
+
const widgetId = xmlWidgetId(props.id, `cm-xml-${absoluteFrom}`);
|
|
8383
|
+
const widgetState = widgetStateMap[widgetId];
|
|
8384
|
+
const mergedProps = {
|
|
8385
|
+
...props,
|
|
8386
|
+
id: widgetId,
|
|
8387
|
+
...widgetState
|
|
8388
|
+
};
|
|
8389
|
+
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8390
|
+
if (widget) {
|
|
8391
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8392
|
+
widget,
|
|
8393
|
+
block: def.block,
|
|
8394
|
+
atomic: true,
|
|
8395
|
+
inclusive: true,
|
|
8396
|
+
tag: tagName,
|
|
8397
|
+
streaming: true,
|
|
8398
|
+
contentFrom
|
|
8399
|
+
}));
|
|
8400
|
+
streamingFrom = absoluteFrom;
|
|
8401
|
+
last = absoluteFrom;
|
|
8402
|
+
}
|
|
8403
|
+
break;
|
|
8404
|
+
}
|
|
8405
|
+
}
|
|
8406
|
+
}
|
|
7556
8407
|
return {
|
|
7557
8408
|
from: last,
|
|
8409
|
+
streamingFrom,
|
|
7558
8410
|
decorations: builder.finish()
|
|
7559
8411
|
};
|
|
7560
8412
|
};
|
|
@@ -7563,108 +8415,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7563
8415
|
Component;
|
|
7564
8416
|
props;
|
|
7565
8417
|
notifier;
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
S: this,
|
|
7573
|
-
A: [
|
|
7574
|
-
"id",
|
|
7575
|
-
""
|
|
7576
|
-
]
|
|
7577
|
-
});
|
|
8418
|
+
streaming;
|
|
8419
|
+
#root = null;
|
|
8420
|
+
#view;
|
|
8421
|
+
constructor(id, Component, props, notifier, streaming) {
|
|
8422
|
+
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8423
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
7578
8424
|
}
|
|
7579
8425
|
get root() {
|
|
7580
|
-
return this
|
|
8426
|
+
return this.#root;
|
|
7581
8427
|
}
|
|
7582
8428
|
eq(other) {
|
|
8429
|
+
if (this.streaming) {
|
|
8430
|
+
return false;
|
|
8431
|
+
}
|
|
7583
8432
|
return this.id === other.id;
|
|
7584
8433
|
}
|
|
7585
8434
|
ignoreEvent() {
|
|
7586
8435
|
return true;
|
|
7587
8436
|
}
|
|
7588
|
-
toDOM(
|
|
7589
|
-
this
|
|
8437
|
+
toDOM(view) {
|
|
8438
|
+
this.#view = view;
|
|
8439
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8440
|
+
const props = Object.assign({}, this.props, {
|
|
8441
|
+
view
|
|
8442
|
+
});
|
|
8443
|
+
this.notifier.mounted({
|
|
8444
|
+
id: this.id,
|
|
8445
|
+
root: this.#root,
|
|
8446
|
+
props,
|
|
8447
|
+
Component: this.Component
|
|
8448
|
+
});
|
|
8449
|
+
return this.#root;
|
|
8450
|
+
}
|
|
8451
|
+
updateDOM(dom) {
|
|
8452
|
+
this.#root = dom;
|
|
8453
|
+
const props = Object.assign({}, this.props, {
|
|
8454
|
+
view: this.#view
|
|
8455
|
+
});
|
|
7590
8456
|
this.notifier.mounted({
|
|
7591
8457
|
id: this.id,
|
|
7592
|
-
root: this
|
|
7593
|
-
props
|
|
8458
|
+
root: this.#root,
|
|
8459
|
+
props,
|
|
7594
8460
|
Component: this.Component
|
|
7595
8461
|
});
|
|
7596
|
-
return
|
|
8462
|
+
return true;
|
|
7597
8463
|
}
|
|
7598
8464
|
destroy(_dom) {
|
|
7599
8465
|
this.notifier.unmounted(this.id);
|
|
7600
|
-
this
|
|
8466
|
+
this.#root = null;
|
|
8467
|
+
this.#view = void 0;
|
|
7601
8468
|
}
|
|
7602
8469
|
};
|
|
7603
|
-
|
|
7604
|
-
// src/extensions/typewriter.ts
|
|
7605
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
7606
|
-
var defaultItems = [
|
|
7607
|
-
"hello world!",
|
|
7608
|
-
"this is a test.",
|
|
7609
|
-
"this is [DXOS](https://dxos.org)"
|
|
7610
|
-
];
|
|
7611
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7612
|
-
let t;
|
|
7613
|
-
let idx = 0;
|
|
7614
|
-
return [
|
|
7615
|
-
keymap14.of([
|
|
7616
|
-
{
|
|
7617
|
-
// Reset.
|
|
7618
|
-
key: "alt-meta-'",
|
|
7619
|
-
run: () => {
|
|
7620
|
-
clearTimeout(t);
|
|
7621
|
-
idx = 0;
|
|
7622
|
-
return true;
|
|
7623
|
-
}
|
|
7624
|
-
},
|
|
7625
|
-
{
|
|
7626
|
-
// Next prompt.
|
|
7627
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
7628
|
-
key: "Shift-Meta-'",
|
|
7629
|
-
run: (view) => {
|
|
7630
|
-
clearTimeout(t);
|
|
7631
|
-
const text = items[idx++];
|
|
7632
|
-
if (idx === items?.length) {
|
|
7633
|
-
idx = 0;
|
|
7634
|
-
}
|
|
7635
|
-
let i = 0;
|
|
7636
|
-
const insert = (d = 0) => {
|
|
7637
|
-
t = setTimeout(() => {
|
|
7638
|
-
const pos = view.state.selection.main.head;
|
|
7639
|
-
view.dispatch({
|
|
7640
|
-
changes: {
|
|
7641
|
-
from: pos,
|
|
7642
|
-
insert: text[i++]
|
|
7643
|
-
},
|
|
7644
|
-
selection: {
|
|
7645
|
-
anchor: pos + 1
|
|
7646
|
-
}
|
|
7647
|
-
});
|
|
7648
|
-
if (i < text.length) {
|
|
7649
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
7650
|
-
}
|
|
7651
|
-
}, d);
|
|
7652
|
-
};
|
|
7653
|
-
insert();
|
|
7654
|
-
return true;
|
|
7655
|
-
}
|
|
7656
|
-
}
|
|
7657
|
-
])
|
|
7658
|
-
];
|
|
7659
|
-
};
|
|
7660
8470
|
export {
|
|
7661
8471
|
Cursor,
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
EditorState3 as EditorState,
|
|
7665
|
-
EditorView30 as EditorView,
|
|
7666
|
-
EditorViewMode,
|
|
7667
|
-
EditorViewModes,
|
|
8472
|
+
EditorState4 as EditorState,
|
|
8473
|
+
EditorView33 as EditorView,
|
|
7668
8474
|
Inline,
|
|
7669
8475
|
InputModeExtensions,
|
|
7670
8476
|
List,
|
|
@@ -7681,6 +8487,7 @@ export {
|
|
|
7681
8487
|
addStyle,
|
|
7682
8488
|
annotations,
|
|
7683
8489
|
autoScroll,
|
|
8490
|
+
autoScrollEffect,
|
|
7684
8491
|
autocomplete,
|
|
7685
8492
|
automerge,
|
|
7686
8493
|
awareness,
|
|
@@ -7694,9 +8501,11 @@ export {
|
|
|
7694
8501
|
commentClickedEffect,
|
|
7695
8502
|
comments,
|
|
7696
8503
|
commentsState,
|
|
8504
|
+
compactSlots,
|
|
7697
8505
|
convertTreeToJson,
|
|
7698
8506
|
createBasicExtensions,
|
|
7699
8507
|
createComment,
|
|
8508
|
+
createCrawler,
|
|
7700
8509
|
createDataExtensions,
|
|
7701
8510
|
createEditorStateStore,
|
|
7702
8511
|
createEditorStateTransaction,
|
|
@@ -7716,12 +8525,12 @@ export {
|
|
|
7716
8525
|
defaultThemeSlots,
|
|
7717
8526
|
deleteItem,
|
|
7718
8527
|
documentId,
|
|
8528
|
+
documentSlots,
|
|
7719
8529
|
dropFile,
|
|
8530
|
+
editorClassNames,
|
|
7720
8531
|
editorInputMode,
|
|
7721
|
-
editorSlots,
|
|
7722
|
-
editorWidth,
|
|
7723
|
-
editorWithToolbarLayout,
|
|
7724
8532
|
extendedMarkdown,
|
|
8533
|
+
fader,
|
|
7725
8534
|
filterChars,
|
|
7726
8535
|
flattenRect,
|
|
7727
8536
|
focus,
|
|
@@ -7757,6 +8566,7 @@ export {
|
|
|
7757
8566
|
markdownTagsExtensions,
|
|
7758
8567
|
matchCompletion,
|
|
7759
8568
|
mention,
|
|
8569
|
+
mobileSlots,
|
|
7760
8570
|
modalStateEffect,
|
|
7761
8571
|
modalStateField,
|
|
7762
8572
|
moveItemDown,
|
|
@@ -7776,9 +8586,12 @@ export {
|
|
|
7776
8586
|
removeList,
|
|
7777
8587
|
removeStyle,
|
|
7778
8588
|
replacer,
|
|
8589
|
+
scrollPastEnd,
|
|
7779
8590
|
scrollThreadIntoView,
|
|
7780
8591
|
scrollToLine,
|
|
7781
|
-
|
|
8592
|
+
scroller,
|
|
8593
|
+
scrollerCrawlEffect,
|
|
8594
|
+
scrollerLineEffect,
|
|
7782
8595
|
selectionState,
|
|
7783
8596
|
setBlockquote,
|
|
7784
8597
|
setComments,
|
|
@@ -7786,10 +8599,8 @@ export {
|
|
|
7786
8599
|
setSelection,
|
|
7787
8600
|
setStyle,
|
|
7788
8601
|
singleValueFacet,
|
|
7789
|
-
|
|
7790
|
-
stackItemContentEditorClassNames,
|
|
8602
|
+
snippets2 as snippets,
|
|
7791
8603
|
staticCompletion,
|
|
7792
|
-
streamer,
|
|
7793
8604
|
submit,
|
|
7794
8605
|
tabbable,
|
|
7795
8606
|
table,
|
|
@@ -7808,7 +8619,12 @@ export {
|
|
|
7808
8619
|
treeFacet,
|
|
7809
8620
|
typeahead,
|
|
7810
8621
|
typewriter,
|
|
8622
|
+
typewriterBypass,
|
|
8623
|
+
typewriterDrainingEffect,
|
|
7811
8624
|
wrapWithCatch,
|
|
8625
|
+
xmlBlockDecoration,
|
|
8626
|
+
xmlElementLength,
|
|
8627
|
+
xmlFormatting,
|
|
7812
8628
|
xmlTagContextEffect,
|
|
7813
8629
|
xmlTagResetEffect,
|
|
7814
8630
|
xmlTagUpdateEffect,
|