@dxos/ui-editor 0.8.4-main.fcfe5033a5 → 0.9.0
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/index.mjs +1258 -1004
- 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 +1258 -1003
- 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.map +1 -1
- package/dist/types/src/extensions/annotations.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 +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts +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 +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +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 +19 -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 +3 -2
- 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/index.d.ts +3 -4
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts +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/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 +13 -2
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/image.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/link.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 -2
- 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/scrolling/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts +83 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/index.d.ts +6 -0
- package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts +15 -0
- package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts +16 -0
- package/dist/types/src/extensions/scrolling/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/spacing.d.ts +3 -0
- package/dist/types/src/extensions/spacing.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.map +1 -1
- package/dist/types/src/extensions/tags/index.d.ts +3 -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 +1 -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/theme.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +2 -2
- package/dist/types/src/types/types.d.ts.map +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 +55 -57
- package/src/defaults.ts +6 -4
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +35 -9
- package/src/extensions/automerge/automerge.ts +1 -1
- package/src/extensions/automerge/cursor.ts +1 -1
- package/src/extensions/automerge/sync.ts +1 -1
- package/src/extensions/automerge/update-automerge.ts +1 -1
- package/src/extensions/comments.ts +54 -31
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +22 -4
- package/src/extensions/index.ts +3 -4
- package/src/extensions/json.ts +1 -1
- package/src/extensions/markdown/decorate.ts +1 -1
- package/src/extensions/markdown/image.test.ts +54 -0
- package/src/extensions/markdown/image.ts +70 -9
- package/src/extensions/markdown/link.ts +7 -2
- package/src/extensions/outliner/outliner.ts +1 -1
- package/src/extensions/preview/preview.ts +14 -12
- package/src/extensions/scrolling/auto-scroll.ts +261 -0
- package/src/extensions/{scroller.ts → scrolling/crawler.ts} +89 -48
- package/src/extensions/scrolling/index.ts +9 -0
- package/src/extensions/{scroll-past-end.ts → scrolling/scroll-past-end.ts} +6 -6
- package/src/extensions/scrolling/scrollbar-autohide.ts +61 -0
- package/src/extensions/scrolling/scroller.ts +27 -0
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/spacing.ts +15 -0
- package/src/extensions/tags/index.ts +3 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/{wire.test.ts → typewriter.test.ts} +2 -2
- 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 +6 -32
- package/src/extensions/tags/xml-util.test.ts +90 -3
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/theme.ts +23 -13
- package/src/typings.d.ts +8 -0
- package/dist/lib/browser/chunk-D724USEC.mjs +0 -34
- package/dist/lib/browser/chunk-D724USEC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-JRVJWKQF.mjs +0 -36
- package/dist/lib/node-esm/chunk-JRVJWKQF.mjs.map +0 -7
- package/dist/types/src/extensions/auto-scroll.d.ts +0 -8
- package/dist/types/src/extensions/auto-scroll.d.ts.map +0 -1
- package/dist/types/src/extensions/scroll-past-end.d.ts.map +0 -1
- package/dist/types/src/extensions/scroller.d.ts +0 -63
- package/dist/types/src/extensions/scroller.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/wire.d.ts +0 -23
- package/dist/types/src/extensions/tags/wire.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/wire.test.d.ts +0 -2
- package/dist/types/src/extensions/tags/wire.test.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/src/extensions/auto-scroll.ts +0 -179
- package/src/extensions/tags/wire.ts +0 -459
- package/src/extensions/typewriter.ts +0 -68
- /package/dist/types/src/extensions/{scroll-past-end.d.ts → scrolling/scroll-past-end.d.ts} +0 -0
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EditorInputMode,
|
|
3
|
-
EditorInputModes,
|
|
4
|
-
EditorViewMode,
|
|
5
|
-
EditorViewModes
|
|
6
|
-
} from "./chunk-D724USEC.mjs";
|
|
7
|
-
|
|
8
1
|
// src/index.ts
|
|
9
2
|
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
10
|
-
import { EditorView as
|
|
3
|
+
import { EditorView as EditorView35, 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 editorClassNames = (role) => mx("dx-attention-surface
|
|
9
|
+
var editorClassNames = (role) => mx("dx-attention-surface data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
17
10
|
var documentSlots = {
|
|
18
11
|
content: {
|
|
19
12
|
/**
|
|
@@ -23,8 +16,11 @@ var documentSlots = {
|
|
|
23
16
|
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
24
17
|
*/
|
|
25
18
|
className: mx(
|
|
26
|
-
//
|
|
27
|
-
|
|
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",
|
|
28
24
|
// Wider margin for web (vs. mobile).
|
|
29
25
|
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
30
26
|
"mx-auto! w-full"
|
|
@@ -275,12 +271,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
275
271
|
} catch (err) {
|
|
276
272
|
log.catch(err, {
|
|
277
273
|
label
|
|
278
|
-
}, {
|
|
279
|
-
F: __dxlog_file,
|
|
280
|
-
L: 20,
|
|
281
|
-
S: void 0,
|
|
282
|
-
C: (f, a) => f(...a)
|
|
283
|
-
});
|
|
274
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
284
275
|
}
|
|
285
276
|
};
|
|
286
277
|
};
|
|
@@ -306,12 +297,7 @@ var logChanges = (trs) => {
|
|
|
306
297
|
if (changes.length) {
|
|
307
298
|
log("changes", {
|
|
308
299
|
changes
|
|
309
|
-
}, {
|
|
310
|
-
F: __dxlog_file,
|
|
311
|
-
L: 54,
|
|
312
|
-
S: void 0,
|
|
313
|
-
C: (f, a) => f(...a)
|
|
314
|
-
});
|
|
300
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
315
301
|
}
|
|
316
302
|
};
|
|
317
303
|
|
|
@@ -377,30 +363,37 @@ var insertAtLineStart = (view, from, insert) => {
|
|
|
377
363
|
};
|
|
378
364
|
|
|
379
365
|
// src/extensions/autocomplete/placeholder.ts
|
|
380
|
-
var placeholder = ({ content, delay = 3e3 }) => {
|
|
366
|
+
var placeholder = ({ content, delay = 3e3, focusOnly = false }) => {
|
|
381
367
|
const plugin = ViewPlugin3.fromClass(class {
|
|
382
368
|
_timeout;
|
|
383
369
|
_decorations = Decoration3.none;
|
|
384
370
|
update(update2) {
|
|
371
|
+
if (!update2.docChanged && !update2.selectionSet && !update2.focusChanged) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
385
374
|
if (this._timeout) {
|
|
386
375
|
window.clearTimeout(this._timeout);
|
|
387
376
|
this._timeout = void 0;
|
|
388
377
|
}
|
|
378
|
+
this._decorations = Decoration3.none;
|
|
379
|
+
if (focusOnly && !update2.view.hasFocus) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
389
382
|
const activeLine = update2.view.state.doc.lineAt(update2.view.state.selection.main.head);
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const lineStart = activeLine.from;
|
|
393
|
-
this._timeout = setTimeout(() => {
|
|
394
|
-
this._decorations = Decoration3.set([
|
|
395
|
-
Decoration3.widget({
|
|
396
|
-
widget: new PlaceholderWidget(content),
|
|
397
|
-
side: 1
|
|
398
|
-
}).range(lineStart)
|
|
399
|
-
]);
|
|
400
|
-
update2.view.update([]);
|
|
401
|
-
}, delay);
|
|
383
|
+
if (activeLine.text.trim() !== "") {
|
|
384
|
+
return;
|
|
402
385
|
}
|
|
403
|
-
|
|
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);
|
|
404
397
|
}
|
|
405
398
|
destroy() {
|
|
406
399
|
if (this._timeout) {
|
|
@@ -518,321 +511,26 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
518
511
|
];
|
|
519
512
|
};
|
|
520
513
|
|
|
521
|
-
// src/extensions/auto-scroll.ts
|
|
522
|
-
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
523
|
-
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
524
|
-
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
525
|
-
import { Domino } from "@dxos/ui";
|
|
526
|
-
import { getSize } from "@dxos/ui-theme";
|
|
527
|
-
|
|
528
|
-
// src/extensions/scroller.ts
|
|
529
|
-
import { StateEffect } from "@codemirror/state";
|
|
530
|
-
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
531
|
-
import { log as log2 } from "@dxos/log";
|
|
532
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
|
|
533
|
-
var scrollerLineEffect = StateEffect.define();
|
|
534
|
-
var scrollerCrawlEffect = StateEffect.define();
|
|
535
|
-
var scrollToLine = (view, options) => {
|
|
536
|
-
view.dispatch({
|
|
537
|
-
effects: scrollerLineEffect.of(options)
|
|
538
|
-
});
|
|
539
|
-
};
|
|
540
|
-
var scroller = ({ overScroll = 0 } = {}) => {
|
|
541
|
-
const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
|
|
542
|
-
view;
|
|
543
|
-
crawler;
|
|
544
|
-
constructor(view) {
|
|
545
|
-
this.view = view;
|
|
546
|
-
this.crawler = createCrawler(this.view);
|
|
547
|
-
}
|
|
548
|
-
// No-op.
|
|
549
|
-
destroy() {
|
|
550
|
-
this.crawler.cancel();
|
|
551
|
-
}
|
|
552
|
-
cancel() {
|
|
553
|
-
this.crawler.cancel();
|
|
554
|
-
}
|
|
555
|
-
crawl(start = false) {
|
|
556
|
-
if (start) {
|
|
557
|
-
this.crawler.scroll();
|
|
558
|
-
} else {
|
|
559
|
-
this.crawler.cancel();
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
563
|
-
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
564
|
-
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
565
|
-
const doc = this.view.state.doc;
|
|
566
|
-
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
567
|
-
if (line >= 0 && line <= doc.lines - 1) {
|
|
568
|
-
const lineStart = doc.line(line + 1).from;
|
|
569
|
-
const coords = this.view.coordsAtPos(lineStart);
|
|
570
|
-
if (coords) {
|
|
571
|
-
const currentScrollTop = scrollTop;
|
|
572
|
-
const maxScrollTop = scrollHeight - clientHeight;
|
|
573
|
-
if (position === "end") {
|
|
574
|
-
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
575
|
-
} else {
|
|
576
|
-
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
577
|
-
}
|
|
578
|
-
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
requestAnimationFrame(() => {
|
|
582
|
-
this.view.scrollDOM.scrollTo({
|
|
583
|
-
top: targetScrollTop
|
|
584
|
-
});
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
});
|
|
588
|
-
return [
|
|
589
|
-
scrollPlugin,
|
|
590
|
-
// Listen for effect.s
|
|
591
|
-
EditorView4.updateListener.of((update2) => {
|
|
592
|
-
update2.transactions.forEach((transaction) => {
|
|
593
|
-
try {
|
|
594
|
-
const plugin = update2.view.plugin(scrollPlugin);
|
|
595
|
-
if (plugin) {
|
|
596
|
-
for (const effect of transaction.effects) {
|
|
597
|
-
if (effect.is(scrollerCrawlEffect)) {
|
|
598
|
-
plugin.crawl(effect.value);
|
|
599
|
-
} else if (effect.is(scrollerLineEffect)) {
|
|
600
|
-
plugin.scroll(effect.value);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
} catch (err) {
|
|
605
|
-
log2.catch(err, void 0, {
|
|
606
|
-
F: __dxlog_file2,
|
|
607
|
-
L: 146,
|
|
608
|
-
S: void 0,
|
|
609
|
-
C: (f, a) => f(...a)
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
}),
|
|
614
|
-
// Styles.
|
|
615
|
-
EditorView4.theme({
|
|
616
|
-
".cm-content": {
|
|
617
|
-
paddingBottom: `${overScroll}px`
|
|
618
|
-
},
|
|
619
|
-
".cm-scroller": {
|
|
620
|
-
overflowY: "scroll",
|
|
621
|
-
overflowAnchor: "none",
|
|
622
|
-
paddingBottom: "0"
|
|
623
|
-
},
|
|
624
|
-
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
625
|
-
display: "none"
|
|
626
|
-
},
|
|
627
|
-
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
628
|
-
background: "transparent",
|
|
629
|
-
transition: "background 0.15s"
|
|
630
|
-
},
|
|
631
|
-
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
632
|
-
background: "var(--color-scrollbar-thumb)"
|
|
633
|
-
},
|
|
634
|
-
".cm-scroll-button": {
|
|
635
|
-
position: "absolute",
|
|
636
|
-
bottom: "0.5rem",
|
|
637
|
-
right: "1rem"
|
|
638
|
-
}
|
|
639
|
-
})
|
|
640
|
-
];
|
|
641
|
-
};
|
|
642
|
-
function createCrawler(view, accel = 0.15, maxVelocity = 1, snapThreshold = 0.5) {
|
|
643
|
-
const el = view.scrollDOM;
|
|
644
|
-
let currentTop = 0;
|
|
645
|
-
let velocity = 0;
|
|
646
|
-
let rafId = null;
|
|
647
|
-
function frame() {
|
|
648
|
-
const targetTop = el.scrollHeight - el.clientHeight;
|
|
649
|
-
const delta = targetTop - currentTop;
|
|
650
|
-
const absDelta = Math.abs(delta);
|
|
651
|
-
if (absDelta < snapThreshold && Math.abs(velocity) < snapThreshold) {
|
|
652
|
-
el.scrollTop = targetTop;
|
|
653
|
-
currentTop = targetTop;
|
|
654
|
-
velocity = 0;
|
|
655
|
-
rafId = null;
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
const stoppingDistance = velocity * velocity / (2 * accel);
|
|
659
|
-
const direction = Math.sign(delta);
|
|
660
|
-
if (velocity !== 0 && (absDelta <= stoppingDistance || direction !== Math.sign(velocity))) {
|
|
661
|
-
velocity -= Math.sign(velocity) * Math.min(accel, Math.abs(velocity));
|
|
662
|
-
} else {
|
|
663
|
-
velocity += direction * accel;
|
|
664
|
-
velocity = Math.sign(velocity) * Math.min(Math.abs(velocity), maxVelocity);
|
|
665
|
-
}
|
|
666
|
-
currentTop += velocity;
|
|
667
|
-
el.scrollTop = currentTop;
|
|
668
|
-
rafId = requestAnimationFrame(frame);
|
|
669
|
-
}
|
|
670
|
-
return {
|
|
671
|
-
scroll: () => {
|
|
672
|
-
if (rafId === null) {
|
|
673
|
-
currentTop = el.scrollTop;
|
|
674
|
-
rafId = requestAnimationFrame(frame);
|
|
675
|
-
}
|
|
676
|
-
},
|
|
677
|
-
cancel: () => {
|
|
678
|
-
if (rafId !== null) {
|
|
679
|
-
cancelAnimationFrame(rafId);
|
|
680
|
-
rafId = null;
|
|
681
|
-
velocity = 0;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
// src/extensions/auto-scroll.ts
|
|
688
|
-
var autoScrollEffect = StateEffect2.define();
|
|
689
|
-
var autoScroll = (_ = {}) => {
|
|
690
|
-
let buttonContainer;
|
|
691
|
-
let isPinned = true;
|
|
692
|
-
let jumpPending = false;
|
|
693
|
-
let enabled = true;
|
|
694
|
-
let firstUpdate = true;
|
|
695
|
-
const setPinned = (pinned) => {
|
|
696
|
-
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
697
|
-
isPinned = pinned;
|
|
698
|
-
};
|
|
699
|
-
return [
|
|
700
|
-
// Update listener for scrolling when content changes.
|
|
701
|
-
EditorView5.updateListener.of((update2) => {
|
|
702
|
-
const { view, heightChanged, state, startState } = update2;
|
|
703
|
-
for (const tr of update2.transactions) {
|
|
704
|
-
for (const effect of tr.effects) {
|
|
705
|
-
if (effect.is(autoScrollEffect)) {
|
|
706
|
-
enabled = effect.value;
|
|
707
|
-
if (enabled) {
|
|
708
|
-
setPinned(true);
|
|
709
|
-
view.dispatch({
|
|
710
|
-
effects: scrollerCrawlEffect.of(true)
|
|
711
|
-
});
|
|
712
|
-
} else {
|
|
713
|
-
view.dispatch({
|
|
714
|
-
effects: scrollerCrawlEffect.of(false)
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
if (!enabled) {
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
724
|
-
firstUpdate = false;
|
|
725
|
-
jumpPending = true;
|
|
726
|
-
requestAnimationFrame(() => {
|
|
727
|
-
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
728
|
-
jumpPending = false;
|
|
729
|
-
});
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
firstUpdate = false;
|
|
733
|
-
if (jumpPending) {
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
if (heightChanged) {
|
|
737
|
-
if (isPinned) {
|
|
738
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
739
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
740
|
-
if (delta > 0) {
|
|
741
|
-
setPinned(true);
|
|
742
|
-
view.dispatch({
|
|
743
|
-
effects: scrollerCrawlEffect.of(true)
|
|
744
|
-
});
|
|
745
|
-
} else if (delta < -1) {
|
|
746
|
-
setPinned(false);
|
|
747
|
-
}
|
|
748
|
-
} else {
|
|
749
|
-
if (state.doc.length === 0) {
|
|
750
|
-
setPinned(true);
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
}),
|
|
755
|
-
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
756
|
-
ViewPlugin6.fromClass(class {
|
|
757
|
-
cleanup;
|
|
758
|
-
constructor(view) {
|
|
759
|
-
this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
|
|
760
|
-
requestAnimationFrame(() => {
|
|
761
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
762
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
763
|
-
const pinned = delta === 0;
|
|
764
|
-
setPinned(pinned);
|
|
765
|
-
if (!pinned) {
|
|
766
|
-
view.dispatch({
|
|
767
|
-
effects: scrollerCrawlEffect.of(false)
|
|
768
|
-
});
|
|
769
|
-
}
|
|
770
|
-
});
|
|
771
|
-
}, 500));
|
|
772
|
-
}
|
|
773
|
-
destroy() {
|
|
774
|
-
this.cleanup();
|
|
775
|
-
}
|
|
776
|
-
}),
|
|
777
|
-
// Scroll button.
|
|
778
|
-
ViewPlugin6.fromClass(class {
|
|
779
|
-
constructor(view) {
|
|
780
|
-
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
781
|
-
icon: "ph--arrow-down--regular"
|
|
782
|
-
});
|
|
783
|
-
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
784
|
-
"data-density": "fine"
|
|
785
|
-
}).append(icon).on("click", () => {
|
|
786
|
-
setPinned(true);
|
|
787
|
-
view.dispatch({
|
|
788
|
-
effects: scrollerLineEffect.of({
|
|
789
|
-
line: -1,
|
|
790
|
-
position: "end",
|
|
791
|
-
behavior: "smooth"
|
|
792
|
-
})
|
|
793
|
-
});
|
|
794
|
-
});
|
|
795
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
796
|
-
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
797
|
-
}
|
|
798
|
-
})
|
|
799
|
-
];
|
|
800
|
-
};
|
|
801
|
-
function createUserScrollDetector(element, onUserScroll) {
|
|
802
|
-
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
803
|
-
passive: true
|
|
804
|
-
}), addEventListener(element, "pointerdown", (event) => {
|
|
805
|
-
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
806
|
-
onUserScroll();
|
|
807
|
-
}
|
|
808
|
-
}));
|
|
809
|
-
}
|
|
810
|
-
|
|
811
514
|
// src/extensions/automerge/automerge.ts
|
|
812
515
|
import { next as A3 } from "@automerge/automerge";
|
|
813
516
|
import { StateField, Transaction as Transaction2 } from "@codemirror/state";
|
|
814
|
-
import { EditorView as
|
|
815
|
-
import { DocAccessor } from "@dxos/echo-
|
|
517
|
+
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
518
|
+
import { DocAccessor } from "@dxos/echo-client";
|
|
816
519
|
|
|
817
520
|
// src/extensions/state.ts
|
|
818
521
|
import { Transaction } from "@codemirror/state";
|
|
819
522
|
var initialSync = Transaction.userEvent.of("initial.sync");
|
|
820
523
|
|
|
821
524
|
// src/extensions/automerge/cursor.ts
|
|
822
|
-
import { fromCursor, toCursor } from "@dxos/echo-
|
|
823
|
-
import { log as
|
|
824
|
-
var
|
|
525
|
+
import { fromCursor, toCursor } from "@dxos/echo-client";
|
|
526
|
+
import { log as log2 } from "@dxos/log";
|
|
527
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
|
|
825
528
|
var cursorConverter = (accessor) => ({
|
|
826
529
|
toCursor: (pos, assoc) => {
|
|
827
530
|
try {
|
|
828
531
|
return toCursor(accessor, pos, assoc);
|
|
829
532
|
} catch (err) {
|
|
830
|
-
|
|
831
|
-
F: __dxlog_file3,
|
|
832
|
-
L: 15,
|
|
833
|
-
S: void 0,
|
|
834
|
-
C: (f, a) => f(...a)
|
|
835
|
-
});
|
|
533
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 11, S: void 0 });
|
|
836
534
|
return "";
|
|
837
535
|
}
|
|
838
536
|
},
|
|
@@ -840,22 +538,17 @@ var cursorConverter = (accessor) => ({
|
|
|
840
538
|
try {
|
|
841
539
|
return fromCursor(accessor, cursor);
|
|
842
540
|
} catch (err) {
|
|
843
|
-
|
|
844
|
-
F: __dxlog_file3,
|
|
845
|
-
L: 24,
|
|
846
|
-
S: void 0,
|
|
847
|
-
C: (f, a) => f(...a)
|
|
848
|
-
});
|
|
541
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 19, S: void 0 });
|
|
849
542
|
return 0;
|
|
850
543
|
}
|
|
851
544
|
}
|
|
852
545
|
});
|
|
853
546
|
|
|
854
547
|
// src/extensions/automerge/defs.ts
|
|
855
|
-
import { Annotation, StateEffect
|
|
548
|
+
import { Annotation, StateEffect } from "@codemirror/state";
|
|
856
549
|
var getPath = (state, field) => state.field(field).path;
|
|
857
550
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
858
|
-
var updateHeadsEffect =
|
|
551
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
859
552
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
860
553
|
newHeads
|
|
861
554
|
});
|
|
@@ -866,7 +559,7 @@ var isReconcile = (tr) => {
|
|
|
866
559
|
|
|
867
560
|
// src/extensions/automerge/sync.ts
|
|
868
561
|
import { next as A2 } from "@automerge/automerge";
|
|
869
|
-
import { log as
|
|
562
|
+
import { log as log3 } from "@dxos/log";
|
|
870
563
|
|
|
871
564
|
// src/extensions/automerge/update-automerge.ts
|
|
872
565
|
import { next as A } from "@automerge/automerge";
|
|
@@ -1007,7 +700,7 @@ var charPath = (textPath, candidatePath) => {
|
|
|
1007
700
|
};
|
|
1008
701
|
|
|
1009
702
|
// src/extensions/automerge/sync.ts
|
|
1010
|
-
var
|
|
703
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
|
|
1011
704
|
var Syncer = class {
|
|
1012
705
|
_handle;
|
|
1013
706
|
_state;
|
|
@@ -1030,12 +723,7 @@ var Syncer = class {
|
|
|
1030
723
|
this._pending = false;
|
|
1031
724
|
}
|
|
1032
725
|
onEditorChange(view) {
|
|
1033
|
-
|
|
1034
|
-
F: __dxlog_file4,
|
|
1035
|
-
L: 45,
|
|
1036
|
-
S: this,
|
|
1037
|
-
C: (f, a) => f(...a)
|
|
1038
|
-
});
|
|
726
|
+
log3("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 35, S: this });
|
|
1039
727
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
1040
728
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
1041
729
|
if (newHeads) {
|
|
@@ -1046,12 +734,7 @@ var Syncer = class {
|
|
|
1046
734
|
}
|
|
1047
735
|
}
|
|
1048
736
|
onAutomergeChange(view) {
|
|
1049
|
-
|
|
1050
|
-
F: __dxlog_file4,
|
|
1051
|
-
L: 60,
|
|
1052
|
-
S: this,
|
|
1053
|
-
C: (f, a) => f(...a)
|
|
1054
|
-
});
|
|
737
|
+
log3("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 47, S: this });
|
|
1055
738
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
1056
739
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
1057
740
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1104,7 +787,7 @@ var automerge = (accessor) => {
|
|
|
1104
787
|
// Track heads.
|
|
1105
788
|
syncState,
|
|
1106
789
|
// Reconcile external updates.
|
|
1107
|
-
|
|
790
|
+
ViewPlugin5.fromClass(class {
|
|
1108
791
|
_view;
|
|
1109
792
|
constructor(_view) {
|
|
1110
793
|
this._view = _view;
|
|
@@ -1135,7 +818,7 @@ var automerge = (accessor) => {
|
|
|
1135
818
|
};
|
|
1136
819
|
}),
|
|
1137
820
|
// Reconcile local updates.
|
|
1138
|
-
|
|
821
|
+
EditorView4.updateListener.of(({ view, changes, transactions }) => {
|
|
1139
822
|
if (!changes.empty) {
|
|
1140
823
|
const isInitialSync = transactions.some((tr) => tr.annotation(Transaction2.userEvent) === initialSync.value);
|
|
1141
824
|
if (!isInitialSync) {
|
|
@@ -1148,10 +831,10 @@ var automerge = (accessor) => {
|
|
|
1148
831
|
|
|
1149
832
|
// src/extensions/awareness/awareness.ts
|
|
1150
833
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
1151
|
-
import { Decoration as Decoration5, EditorView as
|
|
834
|
+
import { Decoration as Decoration5, EditorView as EditorView5, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1152
835
|
import { Event } from "@dxos/async";
|
|
1153
836
|
import { Context } from "@dxos/context";
|
|
1154
|
-
var
|
|
837
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
1155
838
|
var dummyProvider = {
|
|
1156
839
|
remoteStateChange: new Event(),
|
|
1157
840
|
open: () => {
|
|
@@ -1167,17 +850,14 @@ var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
|
1167
850
|
var awareness = (provider = dummyProvider) => {
|
|
1168
851
|
return [
|
|
1169
852
|
awarenessProvider.of(provider),
|
|
1170
|
-
|
|
853
|
+
ViewPlugin6.fromClass(RemoteSelectionsDecorator, {
|
|
1171
854
|
decorations: (value) => value.decorations
|
|
1172
855
|
}),
|
|
1173
856
|
styles
|
|
1174
857
|
];
|
|
1175
858
|
};
|
|
1176
859
|
var RemoteSelectionsDecorator = class {
|
|
1177
|
-
_ctx = new Context(void 0, {
|
|
1178
|
-
F: __dxlog_file5,
|
|
1179
|
-
L: 80
|
|
1180
|
-
});
|
|
860
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 33 });
|
|
1181
861
|
_cursorConverter;
|
|
1182
862
|
_provider;
|
|
1183
863
|
_lastAnchor;
|
|
@@ -1326,7 +1006,7 @@ var RemoteCaretWidget = class extends WidgetType3 {
|
|
|
1326
1006
|
return true;
|
|
1327
1007
|
}
|
|
1328
1008
|
};
|
|
1329
|
-
var styles =
|
|
1009
|
+
var styles = EditorView5.theme({
|
|
1330
1010
|
".cm-collab-selection": {},
|
|
1331
1011
|
".cm-collab-selectionLine": {
|
|
1332
1012
|
padding: 0,
|
|
@@ -1388,8 +1068,8 @@ var styles = EditorView7.theme({
|
|
|
1388
1068
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
1389
1069
|
import { Context as Context2 } from "@dxos/context";
|
|
1390
1070
|
import { invariant } from "@dxos/invariant";
|
|
1391
|
-
import { log as
|
|
1392
|
-
var
|
|
1071
|
+
import { log as log4 } from "@dxos/log";
|
|
1072
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness-provider.ts";
|
|
1393
1073
|
var DEBOUNCE_INTERVAL = 100;
|
|
1394
1074
|
var SpaceAwarenessProvider = class {
|
|
1395
1075
|
_remoteStates = /* @__PURE__ */ new Map();
|
|
@@ -1408,10 +1088,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1408
1088
|
this._info = info;
|
|
1409
1089
|
}
|
|
1410
1090
|
open() {
|
|
1411
|
-
this._ctx = new Context2(void 0, {
|
|
1412
|
-
F: __dxlog_file6,
|
|
1413
|
-
L: 57
|
|
1414
|
-
});
|
|
1091
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 28 });
|
|
1415
1092
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1416
1093
|
if (this._localState) {
|
|
1417
1094
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1436,14 +1113,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1436
1113
|
void this._messenger.postMessage(this._channel, {
|
|
1437
1114
|
kind: "query"
|
|
1438
1115
|
}).catch((err) => {
|
|
1439
|
-
|
|
1116
|
+
log4.debug("failed to query awareness", {
|
|
1440
1117
|
err
|
|
1441
|
-
}, {
|
|
1442
|
-
F: __dxlog_file6,
|
|
1443
|
-
L: 91,
|
|
1444
|
-
S: this,
|
|
1445
|
-
C: (f, a) => f(...a)
|
|
1446
|
-
});
|
|
1118
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 57, S: this });
|
|
1447
1119
|
});
|
|
1448
1120
|
}
|
|
1449
1121
|
close() {
|
|
@@ -1455,15 +1127,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1455
1127
|
return Array.from(this._remoteStates.values());
|
|
1456
1128
|
}
|
|
1457
1129
|
update(position) {
|
|
1458
|
-
invariant(this._postTask, void 0, {
|
|
1459
|
-
F: __dxlog_file6,
|
|
1460
|
-
L: 106,
|
|
1461
|
-
S: this,
|
|
1462
|
-
A: [
|
|
1463
|
-
"this._postTask",
|
|
1464
|
-
""
|
|
1465
|
-
]
|
|
1466
|
-
});
|
|
1130
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1467
1131
|
this._localState = {
|
|
1468
1132
|
peerId: this._peerId,
|
|
1469
1133
|
position,
|
|
@@ -1472,38 +1136,22 @@ var SpaceAwarenessProvider = class {
|
|
|
1472
1136
|
this._postTask.schedule();
|
|
1473
1137
|
}
|
|
1474
1138
|
_handleQueryMessage() {
|
|
1475
|
-
invariant(this._postTask, void 0, {
|
|
1476
|
-
F: __dxlog_file6,
|
|
1477
|
-
L: 117,
|
|
1478
|
-
S: this,
|
|
1479
|
-
A: [
|
|
1480
|
-
"this._postTask",
|
|
1481
|
-
""
|
|
1482
|
-
]
|
|
1483
|
-
});
|
|
1139
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1484
1140
|
this._postTask.schedule();
|
|
1485
1141
|
}
|
|
1486
1142
|
_handlePostMessage(message) {
|
|
1487
|
-
invariant(message.kind === "post", void 0, {
|
|
1488
|
-
F: __dxlog_file6,
|
|
1489
|
-
L: 122,
|
|
1490
|
-
S: this,
|
|
1491
|
-
A: [
|
|
1492
|
-
"message.kind === 'post'",
|
|
1493
|
-
""
|
|
1494
|
-
]
|
|
1495
|
-
});
|
|
1143
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1496
1144
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1497
1145
|
this.remoteStateChange.emit();
|
|
1498
1146
|
}
|
|
1499
1147
|
};
|
|
1500
1148
|
|
|
1501
1149
|
// src/extensions/blast.ts
|
|
1502
|
-
import { EditorView as
|
|
1150
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1503
1151
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1504
|
-
import { throttle
|
|
1152
|
+
import { throttle } from "@dxos/async";
|
|
1505
1153
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1506
|
-
var
|
|
1154
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
|
|
1507
1155
|
var defaultOptions = {
|
|
1508
1156
|
effect: 2,
|
|
1509
1157
|
maxParticles: 200,
|
|
@@ -1548,7 +1196,7 @@ var blast = (options = defaultOptions) => {
|
|
|
1548
1196
|
};
|
|
1549
1197
|
return [
|
|
1550
1198
|
// Cursor moved.
|
|
1551
|
-
|
|
1199
|
+
EditorView6.updateListener.of((update2) => {
|
|
1552
1200
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
1553
1201
|
if (blaster) {
|
|
1554
1202
|
blaster.destroy();
|
|
@@ -1621,15 +1269,7 @@ var Blaster = class {
|
|
|
1621
1269
|
return this._node;
|
|
1622
1270
|
}
|
|
1623
1271
|
initialize() {
|
|
1624
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1625
|
-
F: __dxlog_file7,
|
|
1626
|
-
L: 142,
|
|
1627
|
-
S: this,
|
|
1628
|
-
A: [
|
|
1629
|
-
"!this._canvas && !this._ctx",
|
|
1630
|
-
""
|
|
1631
|
-
]
|
|
1632
|
-
});
|
|
1272
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1633
1273
|
this._canvas = document.createElement("canvas");
|
|
1634
1274
|
this._canvas.id = "code-blast-canvas";
|
|
1635
1275
|
this._canvas.style.position = "absolute";
|
|
@@ -1658,15 +1298,7 @@ var Blaster = class {
|
|
|
1658
1298
|
}
|
|
1659
1299
|
}
|
|
1660
1300
|
start() {
|
|
1661
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1662
|
-
F: __dxlog_file7,
|
|
1663
|
-
L: 181,
|
|
1664
|
-
S: this,
|
|
1665
|
-
A: [
|
|
1666
|
-
"this._canvas && this._ctx",
|
|
1667
|
-
""
|
|
1668
|
-
]
|
|
1669
|
-
});
|
|
1301
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1670
1302
|
this._running = true;
|
|
1671
1303
|
this.loop();
|
|
1672
1304
|
}
|
|
@@ -1693,11 +1325,11 @@ var Blaster = class {
|
|
|
1693
1325
|
this.drawParticles();
|
|
1694
1326
|
requestAnimationFrame(this.loop.bind(this));
|
|
1695
1327
|
}
|
|
1696
|
-
shake =
|
|
1328
|
+
shake = throttle(({ time }) => {
|
|
1697
1329
|
this._shakeTime = this._shakeTimeMax || time;
|
|
1698
1330
|
this._shakeTimeMax = time;
|
|
1699
1331
|
}, 100);
|
|
1700
|
-
spawn =
|
|
1332
|
+
spawn = throttle(({ element, point }) => {
|
|
1701
1333
|
const color = getRGBComponents(element, this._options.color);
|
|
1702
1334
|
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
1703
1335
|
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
@@ -1806,9 +1438,9 @@ var random = (min, max) => {
|
|
|
1806
1438
|
|
|
1807
1439
|
// src/extensions/blocks.ts
|
|
1808
1440
|
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1809
|
-
import { Decoration as Decoration6, EditorView as
|
|
1441
|
+
import { Decoration as Decoration6, EditorView as EditorView7, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
|
1810
1442
|
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1811
|
-
var paragraphBlockPlugin =
|
|
1443
|
+
var paragraphBlockPlugin = ViewPlugin7.fromClass(class {
|
|
1812
1444
|
decorations;
|
|
1813
1445
|
constructor(view) {
|
|
1814
1446
|
this.decorations = this.build(view);
|
|
@@ -1867,7 +1499,7 @@ var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
|
|
|
1867
1499
|
});
|
|
1868
1500
|
var blocks = () => [
|
|
1869
1501
|
paragraphBlockPlugin,
|
|
1870
|
-
|
|
1502
|
+
EditorView7.baseTheme({
|
|
1871
1503
|
".cm-line.block-line": {
|
|
1872
1504
|
paddingLeft: "0.75rem",
|
|
1873
1505
|
paddingRight: "0.75rem",
|
|
@@ -1901,13 +1533,13 @@ var blocks = () => [
|
|
|
1901
1533
|
];
|
|
1902
1534
|
|
|
1903
1535
|
// src/extensions/bookmarks.ts
|
|
1904
|
-
import { Prec as Prec3, StateEffect as
|
|
1536
|
+
import { Prec as Prec3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1905
1537
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1906
|
-
import { log as
|
|
1907
|
-
var
|
|
1908
|
-
var addBookmark =
|
|
1909
|
-
var removeBookmark =
|
|
1910
|
-
var clearBookmarks =
|
|
1538
|
+
import { log as log5 } from "@dxos/log";
|
|
1539
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1540
|
+
var addBookmark = StateEffect2.define();
|
|
1541
|
+
var removeBookmark = StateEffect2.define();
|
|
1542
|
+
var clearBookmarks = StateEffect2.define();
|
|
1911
1543
|
var bookmarks = () => {
|
|
1912
1544
|
return [
|
|
1913
1545
|
bookmarksField,
|
|
@@ -1916,12 +1548,7 @@ var bookmarks = () => {
|
|
|
1916
1548
|
key: "Mod-ArrowUp",
|
|
1917
1549
|
run: (view) => {
|
|
1918
1550
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1919
|
-
|
|
1920
|
-
F: __dxlog_file8,
|
|
1921
|
-
L: 29,
|
|
1922
|
-
S: void 0,
|
|
1923
|
-
C: (f, a) => f(...a)
|
|
1924
|
-
});
|
|
1551
|
+
log5("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 18, S: void 0 });
|
|
1925
1552
|
return true;
|
|
1926
1553
|
}
|
|
1927
1554
|
},
|
|
@@ -1929,12 +1556,7 @@ var bookmarks = () => {
|
|
|
1929
1556
|
key: "Mod-ArrowDown",
|
|
1930
1557
|
run: (view) => {
|
|
1931
1558
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1932
|
-
|
|
1933
|
-
F: __dxlog_file8,
|
|
1934
|
-
L: 37,
|
|
1935
|
-
S: void 0,
|
|
1936
|
-
C: (f, a) => f(...a)
|
|
1937
|
-
});
|
|
1559
|
+
log5("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 26, S: void 0 });
|
|
1938
1560
|
return true;
|
|
1939
1561
|
}
|
|
1940
1562
|
}
|
|
@@ -1971,27 +1593,27 @@ var bookmarksField = StateField2.define({
|
|
|
1971
1593
|
|
|
1972
1594
|
// src/extensions/comments.ts
|
|
1973
1595
|
import { invertedEffects } from "@codemirror/commands";
|
|
1974
|
-
import { StateEffect as
|
|
1975
|
-
import { Decoration as Decoration7, EditorView as
|
|
1596
|
+
import { StateEffect as StateEffect3, StateField as StateField3 } from "@codemirror/state";
|
|
1597
|
+
import { Decoration as Decoration7, EditorView as EditorView9, ViewPlugin as ViewPlugin8, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1976
1598
|
import sortBy from "lodash.sortby";
|
|
1977
1599
|
import { debounce as debounce2 } from "@dxos/async";
|
|
1978
|
-
import { log as
|
|
1600
|
+
import { log as log6 } from "@dxos/log";
|
|
1979
1601
|
import { isNonNullable } from "@dxos/util";
|
|
1980
1602
|
|
|
1981
1603
|
// src/extensions/selection.ts
|
|
1982
1604
|
import { Transaction as Transaction3 } from "@codemirror/state";
|
|
1983
|
-
import { EditorView as
|
|
1605
|
+
import { EditorView as EditorView8, keymap as keymap5 } from "@codemirror/view";
|
|
1984
1606
|
import { debounce } from "@dxos/async";
|
|
1985
1607
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1986
1608
|
import { isTruthy } from "@dxos/util";
|
|
1987
|
-
var
|
|
1609
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1988
1610
|
var documentId = singleValueFacet();
|
|
1989
1611
|
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1990
1612
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1991
1613
|
return {
|
|
1992
1614
|
selection,
|
|
1993
1615
|
scrollIntoView: !scrollTo,
|
|
1994
|
-
effects: scrollTo ?
|
|
1616
|
+
effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
|
|
1995
1617
|
yMargin: 96
|
|
1996
1618
|
}) : void 0,
|
|
1997
1619
|
annotations: Transaction3.userEvent.of(stateRestoreAnnotation)
|
|
@@ -1999,28 +1621,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1999
1621
|
};
|
|
2000
1622
|
var createEditorStateStore = (keyPrefix) => ({
|
|
2001
1623
|
getState: (id) => {
|
|
2002
|
-
invariant3(id, void 0, {
|
|
2003
|
-
F: __dxlog_file9,
|
|
2004
|
-
L: 47,
|
|
2005
|
-
S: void 0,
|
|
2006
|
-
A: [
|
|
2007
|
-
"id",
|
|
2008
|
-
""
|
|
2009
|
-
]
|
|
2010
|
-
});
|
|
1624
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0, A: ["id", ""] });
|
|
2011
1625
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
2012
1626
|
return state ? JSON.parse(state) : void 0;
|
|
2013
1627
|
},
|
|
2014
1628
|
setState: (id, state) => {
|
|
2015
|
-
invariant3(id, void 0, {
|
|
2016
|
-
F: __dxlog_file9,
|
|
2017
|
-
L: 53,
|
|
2018
|
-
S: void 0,
|
|
2019
|
-
A: [
|
|
2020
|
-
"id",
|
|
2021
|
-
""
|
|
2022
|
-
]
|
|
2023
|
-
});
|
|
1629
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 31, S: void 0, A: ["id", ""] });
|
|
2024
1630
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
2025
1631
|
}
|
|
2026
1632
|
});
|
|
@@ -2033,7 +1639,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2033
1639
|
// setStateDebounced(id, {});
|
|
2034
1640
|
// },
|
|
2035
1641
|
// }),
|
|
2036
|
-
|
|
1642
|
+
EditorView8.updateListener.of(({ view, transactions }) => {
|
|
2037
1643
|
const id = view.state.facet(documentId);
|
|
2038
1644
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
|
2039
1645
|
return;
|
|
@@ -2072,10 +1678,10 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2072
1678
|
};
|
|
2073
1679
|
|
|
2074
1680
|
// src/extensions/comments.ts
|
|
2075
|
-
var
|
|
2076
|
-
var setComments =
|
|
2077
|
-
var setSelection =
|
|
2078
|
-
var setCommentState =
|
|
1681
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1682
|
+
var setComments = StateEffect3.define();
|
|
1683
|
+
var setSelection = StateEffect3.define();
|
|
1684
|
+
var setCommentState = StateEffect3.define();
|
|
2079
1685
|
var commentsState = StateField3.define({
|
|
2080
1686
|
create: (state) => ({
|
|
2081
1687
|
id: state.facet(documentId),
|
|
@@ -2114,40 +1720,35 @@ var commentsState = StateField3.define({
|
|
|
2114
1720
|
return value;
|
|
2115
1721
|
}
|
|
2116
1722
|
});
|
|
2117
|
-
var styles2 =
|
|
2118
|
-
".cm-comment
|
|
2119
|
-
padding: "3px 0",
|
|
2120
|
-
color: "var(--color-cm-comment-text)",
|
|
2121
|
-
backgroundColor: "var(--color-cm-comment-surface)"
|
|
2122
|
-
},
|
|
2123
|
-
".cm-comment > span, .cm-comment-current > span": {
|
|
1723
|
+
var styles2 = EditorView9.theme({
|
|
1724
|
+
".cm-comment > span": {
|
|
2124
1725
|
boxDecorationBreak: "clone",
|
|
2125
|
-
boxShadow: "0 0
|
|
1726
|
+
boxShadow: "0 0 0 3px var(--color-cm-comment-surface)",
|
|
2126
1727
|
backgroundColor: "var(--color-cm-comment-surface)",
|
|
2127
|
-
color: "var(--color-cm-comment-text)",
|
|
1728
|
+
color: "var(--color-cm-comment-text) !important",
|
|
2128
1729
|
cursor: "pointer"
|
|
1730
|
+
},
|
|
1731
|
+
'.cm-comment[data-current="1"] > span': {
|
|
1732
|
+
boxShadow: "0 0 0 3px var(--color-cm-comment-current-surface)",
|
|
1733
|
+
backgroundColor: "var(--color-cm-comment-current-surface)"
|
|
2129
1734
|
}
|
|
2130
1735
|
});
|
|
2131
1736
|
var createCommentMark = (id, isCurrent) => Decoration7.mark({
|
|
2132
|
-
class:
|
|
1737
|
+
class: "cm-comment",
|
|
2133
1738
|
attributes: {
|
|
2134
1739
|
"data-testid": "cm-comment",
|
|
2135
|
-
"data-comment-id": id
|
|
1740
|
+
"data-comment-id": id,
|
|
1741
|
+
"data-current": isCurrent ? "1" : "0"
|
|
2136
1742
|
}
|
|
2137
1743
|
});
|
|
2138
|
-
var commentsDecorations =
|
|
1744
|
+
var commentsDecorations = EditorView9.decorations.compute([
|
|
2139
1745
|
commentsState
|
|
2140
1746
|
], (state) => {
|
|
2141
1747
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
2142
1748
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2143
1749
|
const range = comment.range;
|
|
2144
1750
|
if (!range) {
|
|
2145
|
-
|
|
2146
|
-
F: __dxlog_file10,
|
|
2147
|
-
L: 139,
|
|
2148
|
-
S: void 0,
|
|
2149
|
-
C: (f, a) => f(...a)
|
|
2150
|
-
});
|
|
1751
|
+
log6.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 93, S: void 0 });
|
|
2151
1752
|
return void 0;
|
|
2152
1753
|
} else if (range.from === range.to) {
|
|
2153
1754
|
return void 0;
|
|
@@ -2157,8 +1758,8 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2157
1758
|
}).filter(isNonNullable);
|
|
2158
1759
|
return Decoration7.set(decorations2);
|
|
2159
1760
|
});
|
|
2160
|
-
var commentClickedEffect =
|
|
2161
|
-
var handleCommentClick =
|
|
1761
|
+
var commentClickedEffect = StateEffect3.define();
|
|
1762
|
+
var handleCommentClick = EditorView9.domEventHandlers({
|
|
2162
1763
|
click: (event, view) => {
|
|
2163
1764
|
let target = event.target;
|
|
2164
1765
|
const editorRoot = view.dom;
|
|
@@ -2197,7 +1798,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2197
1798
|
}
|
|
2198
1799
|
};
|
|
2199
1800
|
return [
|
|
2200
|
-
|
|
1801
|
+
EditorView9.domEventHandlers({
|
|
2201
1802
|
cut: handleTrack,
|
|
2202
1803
|
copy: handleTrack
|
|
2203
1804
|
}),
|
|
@@ -2219,7 +1820,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2219
1820
|
return effects;
|
|
2220
1821
|
}),
|
|
2221
1822
|
// Handle paste or the undo of comment deletion.
|
|
2222
|
-
|
|
1823
|
+
EditorView9.updateListener.of((update2) => {
|
|
2223
1824
|
const restore = [];
|
|
2224
1825
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
2225
1826
|
const tr = update2.transactions[i];
|
|
@@ -2275,7 +1876,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2275
1876
|
from: changes.mapPos(comment.from, 1),
|
|
2276
1877
|
to: changes.mapPos(comment.to, 1)
|
|
2277
1878
|
});
|
|
2278
|
-
var restoreCommentEffect =
|
|
1879
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
2279
1880
|
map: mapTrackedComment
|
|
2280
1881
|
});
|
|
2281
1882
|
var createComment = (view) => {
|
|
@@ -2361,7 +1962,7 @@ var comments = (options = {}) => {
|
|
|
2361
1962
|
//
|
|
2362
1963
|
// Track deleted ranges and update ranges for decorations.
|
|
2363
1964
|
//
|
|
2364
|
-
|
|
1965
|
+
EditorView9.updateListener.of(({ view, state, changes }) => {
|
|
2365
1966
|
let mod = false;
|
|
2366
1967
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
2367
1968
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -2393,7 +1994,7 @@ var comments = (options = {}) => {
|
|
|
2393
1994
|
//
|
|
2394
1995
|
// Track selection/proximity.
|
|
2395
1996
|
//
|
|
2396
|
-
|
|
1997
|
+
EditorView9.updateListener.of(({ view, state }) => {
|
|
2397
1998
|
let min = Infinity;
|
|
2398
1999
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
2399
2000
|
const { head } = state.selection.main;
|
|
@@ -2429,34 +2030,41 @@ var comments = (options = {}) => {
|
|
|
2429
2030
|
options.onUpdate && trackPastedComments(options.onUpdate)
|
|
2430
2031
|
].filter(isNonNullable);
|
|
2431
2032
|
};
|
|
2432
|
-
var
|
|
2033
|
+
var isRangeVisible = (view, range) => {
|
|
2034
|
+
const from = view.coordsAtPos(range.from);
|
|
2035
|
+
const to = view.coordsAtPos(range.to);
|
|
2036
|
+
if (!from || !to) {
|
|
2037
|
+
return false;
|
|
2038
|
+
}
|
|
2039
|
+
const { top, bottom } = view.scrollDOM.getBoundingClientRect();
|
|
2040
|
+
return from.top >= top && to.bottom <= bottom;
|
|
2041
|
+
};
|
|
2042
|
+
var scrollThreadIntoView = (view, id, { y = "center", yMargin } = {}) => {
|
|
2433
2043
|
const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
|
|
2434
2044
|
if (!comment?.comment.cursor) {
|
|
2435
2045
|
return;
|
|
2436
2046
|
}
|
|
2437
2047
|
const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
|
|
2438
|
-
if (range) {
|
|
2439
|
-
|
|
2440
|
-
const currentScrollPosition = view.scrollDOM.scrollTop;
|
|
2441
|
-
const targetScrollPosition = view.coordsAtPos(range.from)?.top;
|
|
2442
|
-
const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
|
|
2443
|
-
const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
|
|
2444
|
-
if (needsScroll || needsSelectionUpdate) {
|
|
2445
|
-
view.dispatch({
|
|
2446
|
-
selection: needsSelectionUpdate ? {
|
|
2447
|
-
anchor: range.from
|
|
2448
|
-
} : void 0,
|
|
2449
|
-
effects: [
|
|
2450
|
-
needsScroll ? EditorView11.scrollIntoView(range.from, center ? {
|
|
2451
|
-
y: "center"
|
|
2452
|
-
} : void 0) : [],
|
|
2453
|
-
needsSelectionUpdate ? setSelection.of({
|
|
2454
|
-
current: id
|
|
2455
|
-
}) : []
|
|
2456
|
-
].flat()
|
|
2457
|
-
});
|
|
2458
|
-
}
|
|
2048
|
+
if (!range) {
|
|
2049
|
+
return;
|
|
2459
2050
|
}
|
|
2051
|
+
const { from, to } = view.state.selection.main;
|
|
2052
|
+
const needsSelectionUpdate = from !== range.from || to !== range.from;
|
|
2053
|
+
view.dispatch({
|
|
2054
|
+
selection: needsSelectionUpdate ? {
|
|
2055
|
+
anchor: range.from
|
|
2056
|
+
} : void 0,
|
|
2057
|
+
effects: [
|
|
2058
|
+
isRangeVisible(view, range) ? [] : EditorView9.scrollIntoView(range.from, {
|
|
2059
|
+
y,
|
|
2060
|
+
yMargin
|
|
2061
|
+
}),
|
|
2062
|
+
// Always mark this thread current so the highlight follows the selected thread.
|
|
2063
|
+
setSelection.of({
|
|
2064
|
+
current: id
|
|
2065
|
+
})
|
|
2066
|
+
].flat()
|
|
2067
|
+
});
|
|
2460
2068
|
};
|
|
2461
2069
|
var ExternalCommentSync = class {
|
|
2462
2070
|
unsubscribe;
|
|
@@ -2478,7 +2086,7 @@ var ExternalCommentSync = class {
|
|
|
2478
2086
|
this.unsubscribe();
|
|
2479
2087
|
};
|
|
2480
2088
|
};
|
|
2481
|
-
var createExternalCommentSync = (id, subscribe, getComments) =>
|
|
2089
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin8.fromClass(class {
|
|
2482
2090
|
constructor(view) {
|
|
2483
2091
|
return new ExternalCommentSync(view, id, subscribe, getComments);
|
|
2484
2092
|
}
|
|
@@ -2498,12 +2106,12 @@ var debugNodeLogger = (log12 = console.log) => {
|
|
|
2498
2106
|
};
|
|
2499
2107
|
|
|
2500
2108
|
// src/extensions/dnd.ts
|
|
2501
|
-
import { EditorView as
|
|
2109
|
+
import { EditorView as EditorView10, dropCursor } from "@codemirror/view";
|
|
2502
2110
|
var dropFile = (options = {}) => {
|
|
2503
2111
|
return [
|
|
2504
2112
|
styles3,
|
|
2505
2113
|
dropCursor(),
|
|
2506
|
-
|
|
2114
|
+
EditorView10.domEventHandlers({
|
|
2507
2115
|
drop: (event, view) => {
|
|
2508
2116
|
event.preventDefault();
|
|
2509
2117
|
const files = event.dataTransfer?.files;
|
|
@@ -2522,7 +2130,7 @@ var dropFile = (options = {}) => {
|
|
|
2522
2130
|
})
|
|
2523
2131
|
];
|
|
2524
2132
|
};
|
|
2525
|
-
var styles3 =
|
|
2133
|
+
var styles3 = EditorView10.theme({
|
|
2526
2134
|
".cm-dropCursor": {
|
|
2527
2135
|
borderLeft: "2px solid var(--color-accent-text)",
|
|
2528
2136
|
color: "var(--color-accent-text)",
|
|
@@ -2539,15 +2147,15 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2539
2147
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2540
2148
|
import { searchKeymap } from "@codemirror/search";
|
|
2541
2149
|
import { EditorState } from "@codemirror/state";
|
|
2542
|
-
import { EditorView as
|
|
2150
|
+
import { EditorView as EditorView17, ViewPlugin as ViewPlugin13, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2543
2151
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2544
2152
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2545
2153
|
import { generateName } from "@dxos/display-name";
|
|
2546
2154
|
import { log as log8 } from "@dxos/log";
|
|
2547
|
-
import { hexToHue, isTruthy as
|
|
2155
|
+
import { hexToHue, isTruthy as isTruthy3 } from "@dxos/util";
|
|
2548
2156
|
|
|
2549
2157
|
// src/styles/theme.ts
|
|
2550
|
-
import { EditorView as
|
|
2158
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
2551
2159
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2552
2160
|
var headings = {
|
|
2553
2161
|
1: {
|
|
@@ -2595,7 +2203,7 @@ var markdownTheme = {
|
|
|
2595
2203
|
fontWeight: "100 !important"
|
|
2596
2204
|
})
|
|
2597
2205
|
};
|
|
2598
|
-
var baseTheme =
|
|
2206
|
+
var baseTheme = EditorView11.baseTheme({
|
|
2599
2207
|
/**
|
|
2600
2208
|
* Outer frame.
|
|
2601
2209
|
*/
|
|
@@ -2607,12 +2215,21 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2607
2215
|
* Scroller
|
|
2608
2216
|
*/
|
|
2609
2217
|
".cm-scroller": {
|
|
2610
|
-
|
|
2218
|
+
// Browser scroll-anchoring: see comment in `scrolling/crawler.ts`. `auto` lets the browser pin a
|
|
2219
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2220
|
+
// open/close) don't jump the user's view.
|
|
2221
|
+
overflowAnchor: "auto"
|
|
2611
2222
|
},
|
|
2612
2223
|
".cm-scroller::-webkit-scrollbar": {
|
|
2613
|
-
width: "8px"
|
|
2224
|
+
width: "var(--scrollbar-size,8px)",
|
|
2225
|
+
height: "var(--scrollbar-size,8px)"
|
|
2226
|
+
},
|
|
2227
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2228
|
+
background: "transparent"
|
|
2229
|
+
},
|
|
2230
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2231
|
+
background: "transparent"
|
|
2614
2232
|
},
|
|
2615
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2616
2233
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2617
2234
|
background: "transparent",
|
|
2618
2235
|
transition: "background 0.15s"
|
|
@@ -2649,7 +2266,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2649
2266
|
* Height is set to match the corresponding line (which may have wrapped).
|
|
2650
2267
|
*/
|
|
2651
2268
|
".cm-gutterElement": {
|
|
2652
|
-
lineHeight:
|
|
2269
|
+
lineHeight: "24px",
|
|
2653
2270
|
fontSize: "12px"
|
|
2654
2271
|
},
|
|
2655
2272
|
/**
|
|
@@ -2709,7 +2326,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2709
2326
|
textDecorationThickness: "1px",
|
|
2710
2327
|
textDecorationColor: "var(--color-separator)",
|
|
2711
2328
|
textUnderlineOffset: "2px",
|
|
2712
|
-
borderRadius: ".125rem"
|
|
2329
|
+
borderRadius: ".125rem",
|
|
2330
|
+
cursor: "pointer"
|
|
2713
2331
|
},
|
|
2714
2332
|
".cm-link > span": {
|
|
2715
2333
|
color: "var(--color-accent-text)"
|
|
@@ -2747,12 +2365,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2747
2365
|
padding: "4px"
|
|
2748
2366
|
},
|
|
2749
2367
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2750
|
-
background: "var(--color-
|
|
2751
|
-
color: "var(--color-base-
|
|
2368
|
+
background: "var(--color-current-surface)",
|
|
2369
|
+
color: "var(--color-base-fg)"
|
|
2752
2370
|
},
|
|
2753
2371
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2754
2372
|
paddingLeft: "4px !important",
|
|
2755
|
-
color: "var(--color-base-
|
|
2373
|
+
color: "var(--color-base-fg)"
|
|
2756
2374
|
},
|
|
2757
2375
|
/**
|
|
2758
2376
|
* Completion info.
|
|
@@ -2771,7 +2389,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2771
2389
|
padding: "0 4px"
|
|
2772
2390
|
},
|
|
2773
2391
|
".cm-completionMatchedText": {
|
|
2774
|
-
color: "var(--color-base-
|
|
2392
|
+
color: "var(--color-base-fg)",
|
|
2775
2393
|
textDecoration: "none !important"
|
|
2776
2394
|
},
|
|
2777
2395
|
/**
|
|
@@ -2806,7 +2424,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2806
2424
|
backgroundColor: "var(--color-input-surface)"
|
|
2807
2425
|
},
|
|
2808
2426
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2809
|
-
outline: "1px solid var(--color-
|
|
2427
|
+
outline: "1px solid var(--color-focus-ring-subtle)"
|
|
2810
2428
|
},
|
|
2811
2429
|
".cm-panel label": {
|
|
2812
2430
|
display: "inline-flex",
|
|
@@ -2819,15 +2437,15 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2819
2437
|
height: "8px",
|
|
2820
2438
|
marginRight: "6px !important",
|
|
2821
2439
|
padding: "2px !important",
|
|
2822
|
-
color: "var(--color-
|
|
2440
|
+
color: "var(--color-focus-ring-subtle)"
|
|
2823
2441
|
},
|
|
2824
2442
|
".cm-panel button": {
|
|
2825
2443
|
"&:hover": {
|
|
2826
|
-
// TODO(burdon): Replace with layer and @apply bg-accent-
|
|
2827
|
-
backgroundColor: "var(--color-accent-
|
|
2444
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-bg-hover
|
|
2445
|
+
backgroundColor: "var(--color-accent-bg-hover) !important"
|
|
2828
2446
|
},
|
|
2829
2447
|
"&:active": {
|
|
2830
|
-
backgroundColor: "var(--color-accent-
|
|
2448
|
+
backgroundColor: "var(--color-accent-bg-hover)"
|
|
2831
2449
|
}
|
|
2832
2450
|
},
|
|
2833
2451
|
".cm-panel.cm-search": {
|
|
@@ -2835,14 +2453,14 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2835
2453
|
borderTop: "1px solid var(--color-separator)"
|
|
2836
2454
|
}
|
|
2837
2455
|
});
|
|
2838
|
-
var editorGutter =
|
|
2456
|
+
var editorGutter = EditorView11.theme({
|
|
2839
2457
|
".cm-gutters": {
|
|
2840
2458
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2841
2459
|
background: "var(--color-base-surface) !important",
|
|
2842
2460
|
paddingRight: "1rem"
|
|
2843
2461
|
}
|
|
2844
2462
|
});
|
|
2845
|
-
var createFontTheme = ({ monospace } = {}) =>
|
|
2463
|
+
var createFontTheme = ({ monospace } = {}) => EditorView11.theme({
|
|
2846
2464
|
// Main content.
|
|
2847
2465
|
".cm-scroller": {
|
|
2848
2466
|
fontFamily: monospace ? fontMono : fontBody
|
|
@@ -2855,9 +2473,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2855
2473
|
});
|
|
2856
2474
|
|
|
2857
2475
|
// src/extensions/focus.ts
|
|
2858
|
-
import { StateEffect as
|
|
2859
|
-
import { EditorView as
|
|
2860
|
-
var focusEffect =
|
|
2476
|
+
import { StateEffect as StateEffect4, StateField as StateField5 } from "@codemirror/state";
|
|
2477
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
|
2478
|
+
var focusEffect = StateEffect4.define();
|
|
2861
2479
|
var focusField = StateField5.define({
|
|
2862
2480
|
create: () => false,
|
|
2863
2481
|
update: (value, tr) => {
|
|
@@ -2871,7 +2489,7 @@ var focusField = StateField5.define({
|
|
|
2871
2489
|
});
|
|
2872
2490
|
var focus = [
|
|
2873
2491
|
focusField,
|
|
2874
|
-
|
|
2492
|
+
EditorView12.domEventHandlers({
|
|
2875
2493
|
focus: (_event, view) => {
|
|
2876
2494
|
requestAnimationFrame(() => view.dispatch({
|
|
2877
2495
|
effects: focusEffect.of(true)
|
|
@@ -2885,19 +2503,403 @@ var focus = [
|
|
|
2885
2503
|
})
|
|
2886
2504
|
];
|
|
2887
2505
|
|
|
2888
|
-
// src/extensions/scroll
|
|
2506
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2507
|
+
import { StateEffect as StateEffect6 } from "@codemirror/state";
|
|
2508
|
+
import { EditorView as EditorView14, ViewPlugin as ViewPlugin10 } from "@codemirror/view";
|
|
2509
|
+
import { addEventListener, combine, throttle as throttle2 } from "@dxos/async";
|
|
2510
|
+
import { Domino } from "@dxos/ui";
|
|
2511
|
+
import { getSize } from "@dxos/ui-theme";
|
|
2512
|
+
|
|
2513
|
+
// src/extensions/scrolling/crawler.ts
|
|
2514
|
+
import { StateEffect as StateEffect5 } from "@codemirror/state";
|
|
2515
|
+
import { EditorView as EditorView13, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
|
|
2516
|
+
import { log as log7 } from "@dxos/log";
|
|
2517
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scrolling/crawler.ts";
|
|
2518
|
+
var crawlerLineEffect = StateEffect5.define();
|
|
2519
|
+
var crawlerActiveEffect = StateEffect5.define();
|
|
2520
|
+
var scrollToLine = (view, options) => {
|
|
2521
|
+
view.dispatch({
|
|
2522
|
+
effects: crawlerLineEffect.of(options)
|
|
2523
|
+
});
|
|
2524
|
+
};
|
|
2525
|
+
var crawler = ({ overScroll = 0 } = {}) => {
|
|
2526
|
+
const crawlerPlugin = ViewPlugin9.fromClass(class CrawlerPlugin {
|
|
2527
|
+
view;
|
|
2528
|
+
crawler;
|
|
2529
|
+
constructor(view) {
|
|
2530
|
+
this.view = view;
|
|
2531
|
+
this.crawler = createCrawler(this.view);
|
|
2532
|
+
}
|
|
2533
|
+
// No-op.
|
|
2534
|
+
destroy() {
|
|
2535
|
+
this.crawler.cancel();
|
|
2536
|
+
}
|
|
2537
|
+
cancel() {
|
|
2538
|
+
this.crawler.cancel();
|
|
2539
|
+
}
|
|
2540
|
+
crawl({ active, instant } = {
|
|
2541
|
+
active: false
|
|
2542
|
+
}) {
|
|
2543
|
+
if (active) {
|
|
2544
|
+
this.crawler.scroll(instant);
|
|
2545
|
+
} else {
|
|
2546
|
+
this.crawler.cancel();
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
2550
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
2551
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
2552
|
+
const doc = this.view.state.doc;
|
|
2553
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
2554
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
2555
|
+
const lineStart = doc.line(line + 1).from;
|
|
2556
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
2557
|
+
if (coords) {
|
|
2558
|
+
const currentScrollTop = scrollTop;
|
|
2559
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
2560
|
+
if (position === "end") {
|
|
2561
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
2562
|
+
} else {
|
|
2563
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
2564
|
+
}
|
|
2565
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
requestAnimationFrame(() => {
|
|
2569
|
+
this.view.scrollDOM.scrollTo({
|
|
2570
|
+
top: targetScrollTop
|
|
2571
|
+
});
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2574
|
+
});
|
|
2575
|
+
return [
|
|
2576
|
+
crawlerPlugin,
|
|
2577
|
+
// Listen for effect.
|
|
2578
|
+
EditorView13.updateListener.of((update2) => {
|
|
2579
|
+
update2.transactions.forEach((transaction) => {
|
|
2580
|
+
try {
|
|
2581
|
+
const plugin = update2.view.plugin(crawlerPlugin);
|
|
2582
|
+
if (plugin) {
|
|
2583
|
+
for (const effect of transaction.effects) {
|
|
2584
|
+
if (effect.is(crawlerActiveEffect)) {
|
|
2585
|
+
plugin.crawl(effect.value);
|
|
2586
|
+
} else if (effect.is(crawlerLineEffect)) {
|
|
2587
|
+
plugin.scroll(effect.value);
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
} catch (err) {
|
|
2592
|
+
log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 105, S: void 0 });
|
|
2593
|
+
}
|
|
2594
|
+
});
|
|
2595
|
+
}),
|
|
2596
|
+
// Styles.
|
|
2597
|
+
EditorView13.theme({
|
|
2598
|
+
".cm-scroller": {
|
|
2599
|
+
overflowY: "scroll",
|
|
2600
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
2601
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
2602
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
2603
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
2604
|
+
overflowAnchor: "auto"
|
|
2605
|
+
},
|
|
2606
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
2607
|
+
display: "none"
|
|
2608
|
+
},
|
|
2609
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2610
|
+
background: "transparent",
|
|
2611
|
+
transition: "background 0.15s"
|
|
2612
|
+
},
|
|
2613
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2614
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2615
|
+
},
|
|
2616
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
2617
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
2618
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
2619
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
2620
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
2621
|
+
".cm-content::after": {
|
|
2622
|
+
content: '""',
|
|
2623
|
+
display: "block",
|
|
2624
|
+
height: `${overScroll}px`
|
|
2625
|
+
},
|
|
2626
|
+
".cm-scroll-button": {
|
|
2627
|
+
position: "absolute",
|
|
2628
|
+
bottom: "0.5rem",
|
|
2629
|
+
right: "1rem"
|
|
2630
|
+
}
|
|
2631
|
+
})
|
|
2632
|
+
];
|
|
2633
|
+
};
|
|
2634
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
2635
|
+
const el = view.scrollDOM;
|
|
2636
|
+
let currentTop = 0;
|
|
2637
|
+
let velocity = 0;
|
|
2638
|
+
let rafId = null;
|
|
2639
|
+
let lastTime = 0;
|
|
2640
|
+
let instant = false;
|
|
2641
|
+
function frame(now) {
|
|
2642
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
2643
|
+
lastTime = now;
|
|
2644
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
2645
|
+
const delta = targetTop - currentTop;
|
|
2646
|
+
if (instant) {
|
|
2647
|
+
el.scrollTop = targetTop;
|
|
2648
|
+
currentTop = targetTop;
|
|
2649
|
+
velocity = 0;
|
|
2650
|
+
if (Math.abs(delta) < snapThreshold) {
|
|
2651
|
+
rafId = null;
|
|
2652
|
+
lastTime = 0;
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2655
|
+
rafId = requestAnimationFrame(frame);
|
|
2656
|
+
return;
|
|
2657
|
+
}
|
|
2658
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
2659
|
+
el.scrollTop = targetTop;
|
|
2660
|
+
currentTop = targetTop;
|
|
2661
|
+
velocity = 0;
|
|
2662
|
+
rafId = null;
|
|
2663
|
+
lastTime = 0;
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
2667
|
+
velocity += accel * dt;
|
|
2668
|
+
currentTop += velocity * dt;
|
|
2669
|
+
el.scrollTop = currentTop;
|
|
2670
|
+
rafId = requestAnimationFrame(frame);
|
|
2671
|
+
}
|
|
2672
|
+
return {
|
|
2673
|
+
scroll: (useInstant = false) => {
|
|
2674
|
+
instant = useInstant;
|
|
2675
|
+
if (rafId === null) {
|
|
2676
|
+
currentTop = el.scrollTop;
|
|
2677
|
+
lastTime = 0;
|
|
2678
|
+
rafId = requestAnimationFrame(frame);
|
|
2679
|
+
}
|
|
2680
|
+
},
|
|
2681
|
+
cancel: () => {
|
|
2682
|
+
if (rafId !== null) {
|
|
2683
|
+
cancelAnimationFrame(rafId);
|
|
2684
|
+
velocity = 0;
|
|
2685
|
+
lastTime = 0;
|
|
2686
|
+
rafId = null;
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2692
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2693
|
+
var autoScrollEffect = StateEffect6.define();
|
|
2694
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
2695
|
+
let buttonContainer;
|
|
2696
|
+
let isPinned = true;
|
|
2697
|
+
let jumpPending = false;
|
|
2698
|
+
let enabled = true;
|
|
2699
|
+
let firstUpdate = true;
|
|
2700
|
+
let streamed = false;
|
|
2701
|
+
const setPinned = (pinned) => {
|
|
2702
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
2703
|
+
isPinned = pinned;
|
|
2704
|
+
};
|
|
2705
|
+
return [
|
|
2706
|
+
// Update listener for scrolling when content changes.
|
|
2707
|
+
EditorView14.updateListener.of((update2) => {
|
|
2708
|
+
const { view, heightChanged, state, startState } = update2;
|
|
2709
|
+
for (const tr of update2.transactions) {
|
|
2710
|
+
for (const effect of tr.effects) {
|
|
2711
|
+
if (effect.is(autoScrollEffect)) {
|
|
2712
|
+
enabled = effect.value;
|
|
2713
|
+
if (enabled) {
|
|
2714
|
+
setPinned(true);
|
|
2715
|
+
view.dispatch({
|
|
2716
|
+
effects: crawlerActiveEffect.of({
|
|
2717
|
+
active: true
|
|
2718
|
+
})
|
|
2719
|
+
});
|
|
2720
|
+
} else {
|
|
2721
|
+
view.dispatch({
|
|
2722
|
+
effects: crawlerActiveEffect.of({
|
|
2723
|
+
active: false
|
|
2724
|
+
})
|
|
2725
|
+
});
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
if (!enabled) {
|
|
2731
|
+
return;
|
|
2732
|
+
}
|
|
2733
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
2734
|
+
firstUpdate = false;
|
|
2735
|
+
jumpPending = true;
|
|
2736
|
+
requestAnimationFrame(() => {
|
|
2737
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
2738
|
+
jumpPending = false;
|
|
2739
|
+
});
|
|
2740
|
+
return;
|
|
2741
|
+
}
|
|
2742
|
+
firstUpdate = false;
|
|
2743
|
+
if (jumpPending) {
|
|
2744
|
+
return;
|
|
2745
|
+
}
|
|
2746
|
+
if (heightChanged) {
|
|
2747
|
+
if (isPinned) {
|
|
2748
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2749
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2750
|
+
if (update2.docChanged) {
|
|
2751
|
+
streamed = true;
|
|
2752
|
+
}
|
|
2753
|
+
if (delta > 0) {
|
|
2754
|
+
setPinned(true);
|
|
2755
|
+
view.dispatch({
|
|
2756
|
+
effects: crawlerActiveEffect.of({
|
|
2757
|
+
active: true,
|
|
2758
|
+
instant: !streamed
|
|
2759
|
+
})
|
|
2760
|
+
});
|
|
2761
|
+
} else if (delta < -1) {
|
|
2762
|
+
setPinned(false);
|
|
2763
|
+
}
|
|
2764
|
+
} else {
|
|
2765
|
+
if (state.doc.length === 0) {
|
|
2766
|
+
setPinned(true);
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
}),
|
|
2771
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
2772
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
2773
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
2774
|
+
scrollOnResize ? ViewPlugin10.fromClass(class {
|
|
2775
|
+
observer;
|
|
2776
|
+
firstObservation = true;
|
|
2777
|
+
destroyed = false;
|
|
2778
|
+
constructor(view) {
|
|
2779
|
+
const onResize = throttle2(() => {
|
|
2780
|
+
if (this.destroyed || !enabled) {
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
setPinned(true);
|
|
2784
|
+
requestAnimationFrame(() => {
|
|
2785
|
+
if (this.destroyed) {
|
|
2786
|
+
return;
|
|
2787
|
+
}
|
|
2788
|
+
view.scrollDOM.scrollTo({
|
|
2789
|
+
top: view.scrollDOM.scrollHeight,
|
|
2790
|
+
behavior: "instant"
|
|
2791
|
+
});
|
|
2792
|
+
view.dispatch({
|
|
2793
|
+
effects: crawlerActiveEffect.of({
|
|
2794
|
+
active: false
|
|
2795
|
+
})
|
|
2796
|
+
});
|
|
2797
|
+
});
|
|
2798
|
+
}, 50);
|
|
2799
|
+
this.observer = new ResizeObserver(() => {
|
|
2800
|
+
if (this.firstObservation) {
|
|
2801
|
+
this.firstObservation = false;
|
|
2802
|
+
return;
|
|
2803
|
+
}
|
|
2804
|
+
onResize();
|
|
2805
|
+
});
|
|
2806
|
+
this.observer.observe(view.scrollDOM);
|
|
2807
|
+
}
|
|
2808
|
+
destroy() {
|
|
2809
|
+
this.destroyed = true;
|
|
2810
|
+
this.observer.disconnect();
|
|
2811
|
+
}
|
|
2812
|
+
}) : [],
|
|
2813
|
+
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
2814
|
+
ViewPlugin10.fromClass(class {
|
|
2815
|
+
cleanup;
|
|
2816
|
+
constructor(view) {
|
|
2817
|
+
const onUserScroll = throttle2(() => {
|
|
2818
|
+
requestAnimationFrame(() => {
|
|
2819
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2820
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2821
|
+
const pinned = Math.abs(delta) <= 1;
|
|
2822
|
+
setPinned(pinned);
|
|
2823
|
+
if (!pinned) {
|
|
2824
|
+
view.dispatch({
|
|
2825
|
+
effects: crawlerActiveEffect.of({
|
|
2826
|
+
active: false
|
|
2827
|
+
})
|
|
2828
|
+
});
|
|
2829
|
+
}
|
|
2830
|
+
});
|
|
2831
|
+
}, 500);
|
|
2832
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, () => {
|
|
2833
|
+
if (isPinned) {
|
|
2834
|
+
setPinned(false);
|
|
2835
|
+
view.dispatch({
|
|
2836
|
+
effects: crawlerActiveEffect.of({
|
|
2837
|
+
active: false
|
|
2838
|
+
})
|
|
2839
|
+
});
|
|
2840
|
+
}
|
|
2841
|
+
onUserScroll();
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2844
|
+
destroy() {
|
|
2845
|
+
this.cleanup();
|
|
2846
|
+
}
|
|
2847
|
+
}),
|
|
2848
|
+
// Scroll button.
|
|
2849
|
+
ViewPlugin10.fromClass(class {
|
|
2850
|
+
constructor(view) {
|
|
2851
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
2852
|
+
icon: "ph--arrow-down--regular"
|
|
2853
|
+
});
|
|
2854
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-bg").attributes({
|
|
2855
|
+
"data-density": "md"
|
|
2856
|
+
}).append(icon).on("click", () => {
|
|
2857
|
+
setPinned(true);
|
|
2858
|
+
view.dispatch({
|
|
2859
|
+
effects: [
|
|
2860
|
+
crawlerLineEffect.of({
|
|
2861
|
+
line: -1,
|
|
2862
|
+
position: "end",
|
|
2863
|
+
behavior: "smooth"
|
|
2864
|
+
}),
|
|
2865
|
+
// Re-engage the follower so it keeps tracking the bottom as content continues
|
|
2866
|
+
// to stream after the catch-up jump.
|
|
2867
|
+
crawlerActiveEffect.of({
|
|
2868
|
+
active: true,
|
|
2869
|
+
instant: !streamed
|
|
2870
|
+
})
|
|
2871
|
+
]
|
|
2872
|
+
});
|
|
2873
|
+
});
|
|
2874
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0 z-1").append(button).root;
|
|
2875
|
+
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
2876
|
+
}
|
|
2877
|
+
})
|
|
2878
|
+
];
|
|
2879
|
+
};
|
|
2880
|
+
function createUserScrollDetector(element, onUserScroll) {
|
|
2881
|
+
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
2882
|
+
passive: true
|
|
2883
|
+
}), addEventListener(element, "pointerdown", (event) => {
|
|
2884
|
+
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
2885
|
+
onUserScroll();
|
|
2886
|
+
}
|
|
2887
|
+
}));
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2890
|
+
// src/extensions/scrolling/scroll-past-end.ts
|
|
2889
2891
|
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2890
2892
|
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
style:
|
|
2893
|
+
_height = 1e3;
|
|
2894
|
+
_attrs = {
|
|
2895
|
+
style: `padding-bottom: ${this._height}px`
|
|
2894
2896
|
};
|
|
2895
2897
|
update({ view }) {
|
|
2896
2898
|
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2897
2899
|
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2898
|
-
if (height >= 0 && height !== this.
|
|
2899
|
-
this.
|
|
2900
|
-
this.
|
|
2900
|
+
if (height >= 0 && height !== this._height) {
|
|
2901
|
+
this._height = height;
|
|
2902
|
+
this._attrs = {
|
|
2901
2903
|
style: `padding-bottom: ${height}px`
|
|
2902
2904
|
};
|
|
2903
2905
|
}
|
|
@@ -2905,12 +2907,68 @@ var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
|
2905
2907
|
});
|
|
2906
2908
|
var scrollPastEnd = () => [
|
|
2907
2909
|
scrollPastEndPlugin,
|
|
2908
|
-
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.
|
|
2910
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?._attrs ?? null)
|
|
2909
2911
|
];
|
|
2910
2912
|
|
|
2913
|
+
// src/extensions/scrolling/scrollbar-autohide.ts
|
|
2914
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12 } from "@codemirror/view";
|
|
2915
|
+
var scrollbarAutohide = ({ timeout = 800 } = {}) => [
|
|
2916
|
+
ViewPlugin12.fromClass(
|
|
2917
|
+
// NOTE: Uses TS `private`/plain fields rather than ES `#private`. CodeMirror's plugin lifecycle
|
|
2918
|
+
// (and the source/prebundled double-load in dev) can invoke `destroy` with a `this` that the
|
|
2919
|
+
// WeakMap-based `#private` transpilation rejects ("private field on non-instance"), crashing
|
|
2920
|
+
// editor teardown. Plain fields avoid the membership check.
|
|
2921
|
+
class {
|
|
2922
|
+
_scroller;
|
|
2923
|
+
_timer;
|
|
2924
|
+
constructor(view) {
|
|
2925
|
+
this._scroller = view.scrollDOM;
|
|
2926
|
+
this._scroller.addEventListener("scroll", this._handleScroll, {
|
|
2927
|
+
passive: true
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2930
|
+
destroy() {
|
|
2931
|
+
this._scroller.removeEventListener("scroll", this._handleScroll);
|
|
2932
|
+
clearTimeout(this._timer);
|
|
2933
|
+
this._scroller.classList.remove("cm-scrolling");
|
|
2934
|
+
}
|
|
2935
|
+
// Show the thumb while scrolling; remove the class once scrolling has been idle for `timeout`.
|
|
2936
|
+
_handleScroll = () => {
|
|
2937
|
+
this._scroller.classList.add("cm-scrolling");
|
|
2938
|
+
clearTimeout(this._timer);
|
|
2939
|
+
this._timer = setTimeout(() => this._scroller.classList.remove("cm-scrolling"), timeout);
|
|
2940
|
+
};
|
|
2941
|
+
}
|
|
2942
|
+
),
|
|
2943
|
+
EditorView16.theme({
|
|
2944
|
+
// Reveal the thumb only while actively scrolling.
|
|
2945
|
+
".cm-scroller.cm-scrolling::-webkit-scrollbar-thumb": {
|
|
2946
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2947
|
+
},
|
|
2948
|
+
// Suppress the base theme's hover-reveal (higher specificity via `:not(.cm-scrolling)`), so a
|
|
2949
|
+
// hovered/focused-but-idle editor keeps the thumb hidden.
|
|
2950
|
+
"&:hover .cm-scroller:not(.cm-scrolling)::-webkit-scrollbar-thumb": {
|
|
2951
|
+
background: "transparent"
|
|
2952
|
+
}
|
|
2953
|
+
})
|
|
2954
|
+
];
|
|
2955
|
+
|
|
2956
|
+
// src/extensions/scrolling/scroller.ts
|
|
2957
|
+
import { isTruthy as isTruthy2 } from "@dxos/util";
|
|
2958
|
+
var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } = {}) => {
|
|
2959
|
+
return [
|
|
2960
|
+
crawler({
|
|
2961
|
+
overScroll
|
|
2962
|
+
}),
|
|
2963
|
+
autoScroll2 && autoScroll({
|
|
2964
|
+
scrollOnResize
|
|
2965
|
+
})
|
|
2966
|
+
].filter(isTruthy2);
|
|
2967
|
+
};
|
|
2968
|
+
|
|
2911
2969
|
// src/extensions/factories.ts
|
|
2912
2970
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2913
|
-
var tabbable =
|
|
2971
|
+
var tabbable = EditorView17.contentAttributes.of({
|
|
2914
2972
|
tabindex: "0"
|
|
2915
2973
|
});
|
|
2916
2974
|
var filterChars = (chars) => {
|
|
@@ -2963,13 +3021,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2963
3021
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2964
3022
|
return [
|
|
2965
3023
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2966
|
-
|
|
2967
|
-
log8.catch(err, void 0, {
|
|
2968
|
-
F: __dxlog_file11,
|
|
2969
|
-
L: 130,
|
|
2970
|
-
S: void 0,
|
|
2971
|
-
C: (f, a) => f(...a)
|
|
2972
|
-
});
|
|
3024
|
+
EditorView17.exceptionSink.of((err) => {
|
|
3025
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2973
3026
|
}),
|
|
2974
3027
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2975
3028
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2978,7 +3031,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2978
3031
|
props.drawSelection && drawSelection({
|
|
2979
3032
|
cursorBlinkRate: 1200
|
|
2980
3033
|
}),
|
|
2981
|
-
props.editable !== void 0 &&
|
|
3034
|
+
props.editable !== void 0 && EditorView17.editable.of(props.editable),
|
|
2982
3035
|
props.focus && focus,
|
|
2983
3036
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2984
3037
|
props.history && history(),
|
|
@@ -2986,9 +3039,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2986
3039
|
lineNumbers(),
|
|
2987
3040
|
editorGutter
|
|
2988
3041
|
],
|
|
2989
|
-
props.lineWrapping &&
|
|
3042
|
+
props.lineWrapping && EditorView17.lineWrapping,
|
|
2990
3043
|
props.placeholder && placeholder2(props.placeholder),
|
|
2991
3044
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
3045
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
3046
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
3047
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
3048
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
3049
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
3050
|
+
// depend on being able to populate the doc themselves.
|
|
3051
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2992
3052
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2993
3053
|
props.tabbable && tabbable,
|
|
2994
3054
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -3013,8 +3073,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
3013
3073
|
preventDefault: true,
|
|
3014
3074
|
run: () => true
|
|
3015
3075
|
}
|
|
3016
|
-
].filter(
|
|
3017
|
-
].filter(
|
|
3076
|
+
].filter(isTruthy3))
|
|
3077
|
+
].filter(isTruthy3);
|
|
3018
3078
|
};
|
|
3019
3079
|
var grow = {
|
|
3020
3080
|
editor: {
|
|
@@ -3031,29 +3091,32 @@ var defaultStyles = {
|
|
|
3031
3091
|
dark: vscodeDarkStyle,
|
|
3032
3092
|
light: vscodeLightStyle
|
|
3033
3093
|
};
|
|
3034
|
-
var createThemeExtensions = ({ monospace,
|
|
3094
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
3035
3095
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
3036
3096
|
return [
|
|
3037
3097
|
baseTheme,
|
|
3038
|
-
|
|
3098
|
+
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
3039
3099
|
createFontTheme({
|
|
3040
3100
|
monospace
|
|
3041
3101
|
}),
|
|
3042
3102
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
3043
|
-
slots.editor?.className &&
|
|
3103
|
+
slots.editor?.className && EditorView17.editorAttributes.of({
|
|
3044
3104
|
class: slots.editor.className
|
|
3045
3105
|
}),
|
|
3046
|
-
slots.content?.className &&
|
|
3106
|
+
slots.content?.className && EditorView17.contentAttributes.of({
|
|
3047
3107
|
class: slots.content.className
|
|
3048
3108
|
}),
|
|
3049
|
-
slots.scroller?.className &&
|
|
3109
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin13.fromClass(class {
|
|
3050
3110
|
constructor(view) {
|
|
3051
3111
|
if (slots.scroller?.className) {
|
|
3052
3112
|
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
3053
3113
|
}
|
|
3114
|
+
if (scrollbarThin) {
|
|
3115
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
3116
|
+
}
|
|
3054
3117
|
}
|
|
3055
3118
|
})
|
|
3056
|
-
].filter(
|
|
3119
|
+
].filter(isTruthy3);
|
|
3057
3120
|
};
|
|
3058
3121
|
var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
3059
3122
|
const extensions = [];
|
|
@@ -3079,7 +3142,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
3079
3142
|
|
|
3080
3143
|
// src/extensions/folding.ts
|
|
3081
3144
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
3082
|
-
import { EditorView as
|
|
3145
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
3083
3146
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
3084
3147
|
var folding = () => {
|
|
3085
3148
|
return [
|
|
@@ -3094,7 +3157,7 @@ var folding = () => {
|
|
|
3094
3157
|
}))).root;
|
|
3095
3158
|
}
|
|
3096
3159
|
}),
|
|
3097
|
-
|
|
3160
|
+
EditorView18.theme({
|
|
3098
3161
|
".cm-foldGutter": {
|
|
3099
3162
|
opacity: 0.3,
|
|
3100
3163
|
transition: "opacity 0.3s",
|
|
@@ -3108,7 +3171,7 @@ var folding = () => {
|
|
|
3108
3171
|
};
|
|
3109
3172
|
|
|
3110
3173
|
// src/extensions/hashtag.ts
|
|
3111
|
-
import { Decoration as Decoration8, EditorView as
|
|
3174
|
+
import { Decoration as Decoration8, EditorView as EditorView19, MatchDecorator, ViewPlugin as ViewPlugin14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3112
3175
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
3113
3176
|
var TagWidget = class extends WidgetType4 {
|
|
3114
3177
|
_text;
|
|
@@ -3129,7 +3192,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3129
3192
|
})
|
|
3130
3193
|
});
|
|
3131
3194
|
var hashtag = () => [
|
|
3132
|
-
|
|
3195
|
+
ViewPlugin14.fromClass(class {
|
|
3133
3196
|
tags;
|
|
3134
3197
|
constructor(view) {
|
|
3135
3198
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3139,11 +3202,11 @@ var hashtag = () => [
|
|
|
3139
3202
|
}
|
|
3140
3203
|
}, {
|
|
3141
3204
|
decorations: (instance) => instance.tags,
|
|
3142
|
-
provide: (plugin) =>
|
|
3205
|
+
provide: (plugin) => EditorView19.atomicRanges.of((view) => {
|
|
3143
3206
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3144
3207
|
})
|
|
3145
3208
|
}),
|
|
3146
|
-
|
|
3209
|
+
EditorView19.theme({
|
|
3147
3210
|
".cm-tag": {
|
|
3148
3211
|
borderRadius: "4px",
|
|
3149
3212
|
marginRight: "6px",
|
|
@@ -3198,18 +3261,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3198
3261
|
};
|
|
3199
3262
|
|
|
3200
3263
|
// src/extensions/listener.ts
|
|
3201
|
-
import { EditorView as
|
|
3264
|
+
import { EditorView as EditorView20 } from "@codemirror/view";
|
|
3202
3265
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3203
3266
|
var listener = ({ onFocus, onChange }) => {
|
|
3204
3267
|
return [
|
|
3205
|
-
onFocus &&
|
|
3268
|
+
onFocus && EditorView20.focusChangeEffect.of((state, focusing) => {
|
|
3206
3269
|
onFocus({
|
|
3207
3270
|
id: state.facet(documentId),
|
|
3208
3271
|
focusing
|
|
3209
3272
|
});
|
|
3210
3273
|
return null;
|
|
3211
3274
|
}),
|
|
3212
|
-
onChange &&
|
|
3275
|
+
onChange && EditorView20.updateListener.of(({ state, docChanged }) => {
|
|
3213
3276
|
if (docChanged) {
|
|
3214
3277
|
onChange({
|
|
3215
3278
|
id: state.facet(documentId),
|
|
@@ -3224,7 +3287,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3224
3287
|
import { snippet } from "@codemirror/autocomplete";
|
|
3225
3288
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3226
3289
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3227
|
-
import { EditorView as
|
|
3290
|
+
import { EditorView as EditorView21, keymap as keymap8 } from "@codemirror/view";
|
|
3228
3291
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3229
3292
|
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;
|
|
3230
3293
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4313,7 +4376,7 @@ var getFormatting = (state) => {
|
|
|
4313
4376
|
};
|
|
4314
4377
|
};
|
|
4315
4378
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4316
|
-
return
|
|
4379
|
+
return EditorView21.updateListener.of(debounceAndThrottle((update2) => {
|
|
4317
4380
|
if (update2.docChanged || update2.selectionSet) {
|
|
4318
4381
|
onStateChange(getFormatting(update2.state));
|
|
4319
4382
|
}
|
|
@@ -4377,7 +4440,7 @@ import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lan
|
|
|
4377
4440
|
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4378
4441
|
import { languages } from "@codemirror/language-data";
|
|
4379
4442
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4380
|
-
import { isTruthy as
|
|
4443
|
+
import { isTruthy as isTruthy4 } from "@dxos/util";
|
|
4381
4444
|
|
|
4382
4445
|
// src/extensions/markdown/highlight.ts
|
|
4383
4446
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
@@ -4609,7 +4672,7 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4609
4672
|
...defaultKeymap2,
|
|
4610
4673
|
// TODO(burdon): Remove?
|
|
4611
4674
|
...completionKeymap
|
|
4612
|
-
].filter(
|
|
4675
|
+
].filter(isTruthy4))
|
|
4613
4676
|
];
|
|
4614
4677
|
};
|
|
4615
4678
|
var noFencedCodeFolding = {
|
|
@@ -4659,16 +4722,16 @@ var convertTreeToJson = (state) => {
|
|
|
4659
4722
|
|
|
4660
4723
|
// src/extensions/markdown/decorate.ts
|
|
4661
4724
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4662
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4663
|
-
import { Decoration as Decoration11, EditorView as
|
|
4725
|
+
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect8 } from "@codemirror/state";
|
|
4726
|
+
import { Decoration as Decoration11, EditorView as EditorView25, ViewPlugin as ViewPlugin17, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4664
4727
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4665
4728
|
|
|
4666
4729
|
// src/extensions/markdown/changes.ts
|
|
4667
4730
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4668
4731
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4669
|
-
import { ViewPlugin as
|
|
4732
|
+
import { ViewPlugin as ViewPlugin15 } from "@codemirror/view";
|
|
4670
4733
|
var adjustChanges = () => {
|
|
4671
|
-
return
|
|
4734
|
+
return ViewPlugin15.fromClass(class {
|
|
4672
4735
|
update(update2) {
|
|
4673
4736
|
const tree = syntaxTree4(update2.state);
|
|
4674
4737
|
const adjustments = [];
|
|
@@ -4809,15 +4872,19 @@ var getValidUrl = (str) => {
|
|
|
4809
4872
|
|
|
4810
4873
|
// src/extensions/markdown/image.ts
|
|
4811
4874
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4812
|
-
import { StateField as StateField7 } from "@codemirror/state";
|
|
4813
|
-
import { Decoration as Decoration9, EditorView as
|
|
4814
|
-
var
|
|
4875
|
+
import { StateEffect as StateEffect7, StateField as StateField7 } from "@codemirror/state";
|
|
4876
|
+
import { Decoration as Decoration9, EditorView as EditorView22, ViewPlugin as ViewPlugin16, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4877
|
+
var rebuildEffect = StateEffect7.define();
|
|
4878
|
+
var image = (options = {}) => {
|
|
4815
4879
|
return [
|
|
4816
4880
|
StateField7.define({
|
|
4817
4881
|
create: (state) => {
|
|
4818
|
-
return Decoration9.set(buildDecorations(state, 0, state.doc.length));
|
|
4882
|
+
return Decoration9.set(buildDecorations(state, 0, state.doc.length, options));
|
|
4819
4883
|
},
|
|
4820
4884
|
update: (value, tr) => {
|
|
4885
|
+
if (tr.effects.some((effect) => effect.is(rebuildEffect))) {
|
|
4886
|
+
return Decoration9.set(buildDecorations(tr.state, 0, tr.state.doc.length, options));
|
|
4887
|
+
}
|
|
4821
4888
|
if (!tr.docChanged && !tr.selection) {
|
|
4822
4889
|
return value;
|
|
4823
4890
|
}
|
|
@@ -4835,14 +4902,26 @@ var image = (_options = {}) => {
|
|
|
4835
4902
|
filterFrom: from,
|
|
4836
4903
|
filterTo: to,
|
|
4837
4904
|
filter: () => false,
|
|
4838
|
-
add: buildDecorations(tr.state, from, to)
|
|
4905
|
+
add: buildDecorations(tr.state, from, to, options)
|
|
4839
4906
|
});
|
|
4840
4907
|
},
|
|
4841
|
-
provide: (field) =>
|
|
4842
|
-
})
|
|
4908
|
+
provide: (field) => EditorView22.decorations.from(field)
|
|
4909
|
+
}),
|
|
4910
|
+
// Block-replace decorations have to live in a state field, but viewport changes are only
|
|
4911
|
+
// observable from a view plugin. Bridge the two by dispatching a rebuild effect whenever
|
|
4912
|
+
// the viewport extends so newly-parsed image nodes get widgetized without requiring focus.
|
|
4913
|
+
ViewPlugin16.define((view) => ({
|
|
4914
|
+
update: (update2) => {
|
|
4915
|
+
if (update2.viewportChanged) {
|
|
4916
|
+
queueMicrotask(() => view.dispatch({
|
|
4917
|
+
effects: rebuildEffect.of(void 0)
|
|
4918
|
+
}));
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
}))
|
|
4843
4922
|
];
|
|
4844
4923
|
};
|
|
4845
|
-
var buildDecorations = (state, from, to) => {
|
|
4924
|
+
var buildDecorations = (state, from, to, options = {}) => {
|
|
4846
4925
|
const decorations2 = [];
|
|
4847
4926
|
const cursor = state.selection.main.head;
|
|
4848
4927
|
syntaxTree5(state).iterate({
|
|
@@ -4855,6 +4934,12 @@ var buildDecorations = (state, from, to) => {
|
|
|
4855
4934
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4856
4935
|
return;
|
|
4857
4936
|
}
|
|
4937
|
+
if (options.skip?.({
|
|
4938
|
+
name: "Image",
|
|
4939
|
+
url
|
|
4940
|
+
})) {
|
|
4941
|
+
return;
|
|
4942
|
+
}
|
|
4858
4943
|
preloadImage(url);
|
|
4859
4944
|
decorations2.push(Decoration9.replace({
|
|
4860
4945
|
block: true,
|
|
@@ -4888,20 +4973,34 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4888
4973
|
const img = document.createElement("img");
|
|
4889
4974
|
img.setAttribute("src", this._url);
|
|
4890
4975
|
img.setAttribute("class", "cm-image");
|
|
4891
|
-
|
|
4892
|
-
|
|
4976
|
+
const focused = view.state.field(focusField);
|
|
4977
|
+
if (focused) {
|
|
4978
|
+
img.onload = () => {
|
|
4979
|
+
img.classList.add("cm-loaded-image");
|
|
4980
|
+
collapseIfTrackingPixel(img);
|
|
4981
|
+
};
|
|
4893
4982
|
} else {
|
|
4894
4983
|
img.classList.add("cm-loaded-image");
|
|
4984
|
+
img.onload = () => collapseIfTrackingPixel(img);
|
|
4895
4985
|
}
|
|
4986
|
+
img.onerror = () => collapseLine(img);
|
|
4896
4987
|
return img;
|
|
4897
4988
|
}
|
|
4898
4989
|
};
|
|
4990
|
+
var collapseIfTrackingPixel = (img) => {
|
|
4991
|
+
if (img.naturalWidth <= 1 && img.naturalHeight <= 1) {
|
|
4992
|
+
collapseLine(img);
|
|
4993
|
+
}
|
|
4994
|
+
};
|
|
4995
|
+
var collapseLine = (img) => {
|
|
4996
|
+
img.style.display = "none";
|
|
4997
|
+
};
|
|
4899
4998
|
|
|
4900
4999
|
// src/extensions/markdown/styles.ts
|
|
4901
|
-
import { EditorView as
|
|
5000
|
+
import { EditorView as EditorView23 } from "@codemirror/view";
|
|
4902
5001
|
var bulletListIndentationWidth = 24;
|
|
4903
5002
|
var orderedListIndentationWidth = 36;
|
|
4904
|
-
var formattingStyles =
|
|
5003
|
+
var formattingStyles = EditorView23.theme({
|
|
4905
5004
|
/**
|
|
4906
5005
|
* Horizontal rule.
|
|
4907
5006
|
*/
|
|
@@ -5056,12 +5155,12 @@ var formattingStyles = EditorView22.theme({
|
|
|
5056
5155
|
// src/extensions/markdown/table.ts
|
|
5057
5156
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
5058
5157
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
5059
|
-
import { Decoration as Decoration10, EditorView as
|
|
5158
|
+
import { Decoration as Decoration10, EditorView as EditorView24, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
5060
5159
|
var table = (options = {}) => {
|
|
5061
5160
|
return StateField8.define({
|
|
5062
5161
|
create: (state) => update(state, options),
|
|
5063
5162
|
update: (_, tr) => update(tr.state, options),
|
|
5064
|
-
provide: (field) =>
|
|
5163
|
+
provide: (field) => EditorView24.decorations.from(field)
|
|
5065
5164
|
});
|
|
5066
5165
|
};
|
|
5067
5166
|
var update = (state, _options) => {
|
|
@@ -5307,15 +5406,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5307
5406
|
const { state } = view;
|
|
5308
5407
|
const headerLevels = [];
|
|
5309
5408
|
const getHeaderLevels = (node, level) => {
|
|
5310
|
-
invariant4(level > 0, void 0, {
|
|
5311
|
-
F: __dxlog_file12,
|
|
5312
|
-
L: 177,
|
|
5313
|
-
S: void 0,
|
|
5314
|
-
A: [
|
|
5315
|
-
"level > 0",
|
|
5316
|
-
""
|
|
5317
|
-
]
|
|
5318
|
-
});
|
|
5409
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5319
5410
|
if (level > headerLevels.length) {
|
|
5320
5411
|
const len = headerLevels.length;
|
|
5321
5412
|
headerLevels.length = level;
|
|
@@ -5346,15 +5437,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5346
5437
|
listLevels.pop();
|
|
5347
5438
|
};
|
|
5348
5439
|
const getCurrentListLevel = () => {
|
|
5349
|
-
invariant4(listLevels.length, void 0, {
|
|
5350
|
-
F: __dxlog_file12,
|
|
5351
|
-
L: 199,
|
|
5352
|
-
S: void 0,
|
|
5353
|
-
A: [
|
|
5354
|
-
"listLevels.length",
|
|
5355
|
-
""
|
|
5356
|
-
]
|
|
5357
|
-
});
|
|
5440
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5358
5441
|
return listLevels[listLevels.length - 1];
|
|
5359
5442
|
};
|
|
5360
5443
|
const enterNode = (node) => {
|
|
@@ -5668,10 +5751,10 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5668
5751
|
atomicDeco: atomicDeco.finish()
|
|
5669
5752
|
};
|
|
5670
5753
|
};
|
|
5671
|
-
var forceUpdate =
|
|
5754
|
+
var forceUpdate = StateEffect8.define();
|
|
5672
5755
|
var decorateMarkdown = (options = {}) => {
|
|
5673
5756
|
return [
|
|
5674
|
-
|
|
5757
|
+
ViewPlugin17.fromClass(class {
|
|
5675
5758
|
deco;
|
|
5676
5759
|
atomicDeco;
|
|
5677
5760
|
pendingUpdate;
|
|
@@ -5706,12 +5789,14 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5706
5789
|
}
|
|
5707
5790
|
}, {
|
|
5708
5791
|
provide: (plugin) => [
|
|
5709
|
-
Prec4.low(
|
|
5710
|
-
|
|
5711
|
-
|
|
5792
|
+
Prec4.low(EditorView25.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5793
|
+
EditorView25.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5794
|
+
EditorView25.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5712
5795
|
]
|
|
5713
5796
|
}),
|
|
5714
|
-
image(
|
|
5797
|
+
image({
|
|
5798
|
+
skip: options.skip ? (node) => !!options.skip?.(node) : void 0
|
|
5799
|
+
}),
|
|
5715
5800
|
table(),
|
|
5716
5801
|
adjustChanges(),
|
|
5717
5802
|
formattingStyles
|
|
@@ -5721,7 +5806,10 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5721
5806
|
// src/extensions/markdown/link.ts
|
|
5722
5807
|
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
5723
5808
|
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
|
5724
|
-
import {
|
|
5809
|
+
import { mx as mx6, surfaceShadow } from "@dxos/ui-theme";
|
|
5810
|
+
var tooltipClassName = mx6("inline-flex items-center p-1 max-w-64 text-sm bg-inverse-surface text-inverse-fg rounded-sm", surfaceShadow({
|
|
5811
|
+
elevation: "positioned"
|
|
5812
|
+
}));
|
|
5725
5813
|
var linkTooltip = (renderTooltip) => {
|
|
5726
5814
|
return hoverTooltip2((view, pos, side) => {
|
|
5727
5815
|
const syntax = syntaxTree8(view.state).resolveInner(pos, side);
|
|
@@ -5743,7 +5831,7 @@ var linkTooltip = (renderTooltip) => {
|
|
|
5743
5831
|
above: true,
|
|
5744
5832
|
create: () => {
|
|
5745
5833
|
const el = document.createElement("div");
|
|
5746
|
-
el.className =
|
|
5834
|
+
el.className = tooltipClassName;
|
|
5747
5835
|
renderTooltip(el, {
|
|
5748
5836
|
url: urlText
|
|
5749
5837
|
}, view);
|
|
@@ -5776,12 +5864,7 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5776
5864
|
(context) => {
|
|
5777
5865
|
log9.info("completion context", {
|
|
5778
5866
|
context
|
|
5779
|
-
}, {
|
|
5780
|
-
F: __dxlog_file13,
|
|
5781
|
-
L: 27,
|
|
5782
|
-
S: void 0,
|
|
5783
|
-
C: (f, a) => f(...a)
|
|
5784
|
-
});
|
|
5867
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5785
5868
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5786
5869
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5787
5870
|
return null;
|
|
@@ -5798,8 +5881,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5798
5881
|
};
|
|
5799
5882
|
|
|
5800
5883
|
// src/extensions/modal.ts
|
|
5801
|
-
import { StateEffect as
|
|
5802
|
-
var modalStateEffect =
|
|
5884
|
+
import { StateEffect as StateEffect9, StateField as StateField9 } from "@codemirror/state";
|
|
5885
|
+
var modalStateEffect = StateEffect9.define();
|
|
5803
5886
|
var modalStateField = StateField9.define({
|
|
5804
5887
|
create: () => false,
|
|
5805
5888
|
update: (value, tr) => {
|
|
@@ -6014,15 +6097,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
6014
6097
|
break;
|
|
6015
6098
|
}
|
|
6016
6099
|
case "BulletList": {
|
|
6017
|
-
invariant5(current, void 0, {
|
|
6018
|
-
F: __dxlog_file14,
|
|
6019
|
-
L: 219,
|
|
6020
|
-
S: void 0,
|
|
6021
|
-
A: [
|
|
6022
|
-
"current",
|
|
6023
|
-
""
|
|
6024
|
-
]
|
|
6025
|
-
});
|
|
6100
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
6026
6101
|
parent = current;
|
|
6027
6102
|
if (current) {
|
|
6028
6103
|
current.lineRange.to = current.node.from;
|
|
@@ -6031,15 +6106,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
6031
6106
|
break;
|
|
6032
6107
|
}
|
|
6033
6108
|
case "ListItem": {
|
|
6034
|
-
invariant5(parent, void 0, {
|
|
6035
|
-
F: __dxlog_file14,
|
|
6036
|
-
L: 228,
|
|
6037
|
-
S: void 0,
|
|
6038
|
-
A: [
|
|
6039
|
-
"parent",
|
|
6040
|
-
""
|
|
6041
|
-
]
|
|
6042
|
-
});
|
|
6109
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
6043
6110
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
6044
6111
|
const docRange = {
|
|
6045
6112
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -6073,42 +6140,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
6073
6140
|
break;
|
|
6074
6141
|
}
|
|
6075
6142
|
case "ListMark": {
|
|
6076
|
-
invariant5(current, void 0, {
|
|
6077
|
-
F: __dxlog_file14,
|
|
6078
|
-
L: 272,
|
|
6079
|
-
S: void 0,
|
|
6080
|
-
A: [
|
|
6081
|
-
"current",
|
|
6082
|
-
""
|
|
6083
|
-
]
|
|
6084
|
-
});
|
|
6143
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
6085
6144
|
current.type = "bullet";
|
|
6086
6145
|
current.contentRange.from = node.from + "- ".length;
|
|
6087
6146
|
break;
|
|
6088
6147
|
}
|
|
6089
6148
|
case "Task": {
|
|
6090
|
-
invariant5(current, void 0, {
|
|
6091
|
-
F: __dxlog_file14,
|
|
6092
|
-
L: 278,
|
|
6093
|
-
S: void 0,
|
|
6094
|
-
A: [
|
|
6095
|
-
"current",
|
|
6096
|
-
""
|
|
6097
|
-
]
|
|
6098
|
-
});
|
|
6149
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
6099
6150
|
current.type = "task";
|
|
6100
6151
|
break;
|
|
6101
6152
|
}
|
|
6102
6153
|
case "TaskMarker": {
|
|
6103
|
-
invariant5(current, void 0, {
|
|
6104
|
-
F: __dxlog_file14,
|
|
6105
|
-
L: 283,
|
|
6106
|
-
S: void 0,
|
|
6107
|
-
A: [
|
|
6108
|
-
"current",
|
|
6109
|
-
""
|
|
6110
|
-
]
|
|
6111
|
-
});
|
|
6154
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
6112
6155
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
6113
6156
|
break;
|
|
6114
6157
|
}
|
|
@@ -6116,29 +6159,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
6116
6159
|
},
|
|
6117
6160
|
leave: (node) => {
|
|
6118
6161
|
if (node.name === "BulletList") {
|
|
6119
|
-
invariant5(parent, void 0, {
|
|
6120
|
-
F: __dxlog_file14,
|
|
6121
|
-
L: 291,
|
|
6122
|
-
S: void 0,
|
|
6123
|
-
A: [
|
|
6124
|
-
"parent",
|
|
6125
|
-
""
|
|
6126
|
-
]
|
|
6127
|
-
});
|
|
6162
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
6128
6163
|
prevSiblings[level--] = void 0;
|
|
6129
6164
|
parent = parent.parent;
|
|
6130
6165
|
}
|
|
6131
6166
|
}
|
|
6132
6167
|
});
|
|
6133
|
-
invariant5(tree, void 0, {
|
|
6134
|
-
F: __dxlog_file14,
|
|
6135
|
-
L: 298,
|
|
6136
|
-
S: void 0,
|
|
6137
|
-
A: [
|
|
6138
|
-
"tree",
|
|
6139
|
-
""
|
|
6140
|
-
]
|
|
6141
|
-
});
|
|
6168
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
6142
6169
|
return tree;
|
|
6143
6170
|
};
|
|
6144
6171
|
return [
|
|
@@ -6423,17 +6450,17 @@ var commands = () => keymap11.of([
|
|
|
6423
6450
|
|
|
6424
6451
|
// src/extensions/outliner/outliner.ts
|
|
6425
6452
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6426
|
-
import { Decoration as Decoration12, EditorView as
|
|
6427
|
-
import { mx as
|
|
6453
|
+
import { Decoration as Decoration12, EditorView as EditorView27, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
6454
|
+
import { mx as mx7 } from "@dxos/ui-theme";
|
|
6428
6455
|
|
|
6429
6456
|
// src/extensions/outliner/editor.ts
|
|
6430
6457
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6431
|
-
import { ViewPlugin as
|
|
6458
|
+
import { ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6432
6459
|
import { log as log10 } from "@dxos/log";
|
|
6433
6460
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6434
6461
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6435
6462
|
var initialize = () => {
|
|
6436
|
-
return
|
|
6463
|
+
return ViewPlugin18.fromClass(class {
|
|
6437
6464
|
constructor(view) {
|
|
6438
6465
|
const first = view.state.doc.lineAt(0);
|
|
6439
6466
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6580,35 +6607,20 @@ var editor = () => [
|
|
|
6580
6607
|
text: insert.toString(),
|
|
6581
6608
|
length: insert.length
|
|
6582
6609
|
}
|
|
6583
|
-
}, {
|
|
6584
|
-
F: __dxlog_file15,
|
|
6585
|
-
L: 164,
|
|
6586
|
-
S: void 0,
|
|
6587
|
-
C: (f, a) => f(...a)
|
|
6588
|
-
});
|
|
6610
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6589
6611
|
}
|
|
6590
6612
|
});
|
|
6591
6613
|
if (changes.length > 0) {
|
|
6592
6614
|
log10("modified,", {
|
|
6593
6615
|
changes
|
|
6594
|
-
}, {
|
|
6595
|
-
F: __dxlog_file15,
|
|
6596
|
-
L: 175,
|
|
6597
|
-
S: void 0,
|
|
6598
|
-
C: (f, a) => f(...a)
|
|
6599
|
-
});
|
|
6616
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6600
6617
|
return [
|
|
6601
6618
|
{
|
|
6602
6619
|
changes
|
|
6603
6620
|
}
|
|
6604
6621
|
];
|
|
6605
6622
|
} else if (cancel) {
|
|
6606
|
-
log10("cancel", void 0, {
|
|
6607
|
-
F: __dxlog_file15,
|
|
6608
|
-
L: 178,
|
|
6609
|
-
S: void 0,
|
|
6610
|
-
C: (f, a) => f(...a)
|
|
6611
|
-
});
|
|
6623
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6612
6624
|
return [];
|
|
6613
6625
|
}
|
|
6614
6626
|
return tr;
|
|
@@ -6616,10 +6628,10 @@ var editor = () => [
|
|
|
6616
6628
|
];
|
|
6617
6629
|
|
|
6618
6630
|
// src/extensions/outliner/menu.ts
|
|
6619
|
-
import { EditorView as
|
|
6631
|
+
import { EditorView as EditorView26, ViewPlugin as ViewPlugin19 } from "@codemirror/view";
|
|
6620
6632
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6621
6633
|
var menu = (options = {}) => [
|
|
6622
|
-
|
|
6634
|
+
ViewPlugin19.fromClass(class {
|
|
6623
6635
|
view;
|
|
6624
6636
|
tag;
|
|
6625
6637
|
rafId;
|
|
@@ -6681,7 +6693,7 @@ var menu = (options = {}) => [
|
|
|
6681
6693
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6682
6694
|
}
|
|
6683
6695
|
}),
|
|
6684
|
-
|
|
6696
|
+
EditorView26.theme({
|
|
6685
6697
|
".cm-popover-trigger": {
|
|
6686
6698
|
position: "fixed",
|
|
6687
6699
|
padding: "0",
|
|
@@ -6717,12 +6729,12 @@ var outliner = (_options = {}) => [
|
|
|
6717
6729
|
listPaddingLeft: 8
|
|
6718
6730
|
}),
|
|
6719
6731
|
// Researve space for menu.
|
|
6720
|
-
|
|
6732
|
+
EditorView27.contentAttributes.of({
|
|
6721
6733
|
class: "w-full !mr-[3rem]"
|
|
6722
6734
|
})
|
|
6723
6735
|
];
|
|
6724
6736
|
var decorations = () => [
|
|
6725
|
-
|
|
6737
|
+
ViewPlugin20.fromClass(class {
|
|
6726
6738
|
decorations = Decoration12.none;
|
|
6727
6739
|
constructor(view) {
|
|
6728
6740
|
this.updateDecorations(view.state, view);
|
|
@@ -6747,7 +6759,7 @@ var decorations = () => [
|
|
|
6747
6759
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6748
6760
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6749
6761
|
decorations2.push(Decoration12.line({
|
|
6750
|
-
class:
|
|
6762
|
+
class: mx7("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"))
|
|
6751
6763
|
}).range(line.from, line.from));
|
|
6752
6764
|
}
|
|
6753
6765
|
}
|
|
@@ -6757,7 +6769,7 @@ var decorations = () => [
|
|
|
6757
6769
|
decorations: (v) => v.decorations
|
|
6758
6770
|
}),
|
|
6759
6771
|
// Theme.
|
|
6760
|
-
|
|
6772
|
+
EditorView27.theme(Object.assign({
|
|
6761
6773
|
".cm-list-item": {
|
|
6762
6774
|
borderLeftWidth: "1px",
|
|
6763
6775
|
borderRightWidth: "1px",
|
|
@@ -6782,7 +6794,7 @@ var decorations = () => [
|
|
|
6782
6794
|
marginBottom: "2px"
|
|
6783
6795
|
},
|
|
6784
6796
|
".cm-list-item-focused": {
|
|
6785
|
-
borderColor: "var(--color-
|
|
6797
|
+
borderColor: "var(--color-focus-ring-subtle)"
|
|
6786
6798
|
},
|
|
6787
6799
|
"&:focus-within .cm-list-item-selected": {
|
|
6788
6800
|
borderColor: "var(--color-separator)"
|
|
@@ -6792,10 +6804,11 @@ var decorations = () => [
|
|
|
6792
6804
|
|
|
6793
6805
|
// src/extensions/preview/preview.ts
|
|
6794
6806
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6795
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as
|
|
6796
|
-
import { Decoration as Decoration13, EditorView as
|
|
6797
|
-
import {
|
|
6798
|
-
|
|
6807
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect10, StateField as StateField11 } from "@codemirror/state";
|
|
6808
|
+
import { Decoration as Decoration13, EditorView as EditorView28, ViewPlugin as ViewPlugin21, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6809
|
+
import { Entity } from "@dxos/echo";
|
|
6810
|
+
import { EID, URI } from "@dxos/keys";
|
|
6811
|
+
var labelResolvedEffect = StateEffect10.define();
|
|
6799
6812
|
var preview = (options = {}) => {
|
|
6800
6813
|
const viewRef = {
|
|
6801
6814
|
current: void 0
|
|
@@ -6812,11 +6825,11 @@ var preview = (options = {}) => {
|
|
|
6812
6825
|
return decorations2.map(tr.changes);
|
|
6813
6826
|
},
|
|
6814
6827
|
provide: (field) => [
|
|
6815
|
-
|
|
6816
|
-
|
|
6828
|
+
EditorView28.decorations.from(field),
|
|
6829
|
+
EditorView28.atomicRanges.of((view) => view.state.field(field))
|
|
6817
6830
|
]
|
|
6818
6831
|
}),
|
|
6819
|
-
|
|
6832
|
+
ViewPlugin21.define((view) => {
|
|
6820
6833
|
viewRef.current = view;
|
|
6821
6834
|
return {
|
|
6822
6835
|
destroy() {
|
|
@@ -6827,11 +6840,12 @@ var preview = (options = {}) => {
|
|
|
6827
6840
|
];
|
|
6828
6841
|
};
|
|
6829
6842
|
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6830
|
-
const
|
|
6831
|
-
|
|
6843
|
+
const echoUri = EID.tryParse(dxnStr);
|
|
6844
|
+
const dxnRef = echoUri ?? (dxnStr.startsWith("dxn:") ? URI.make(dxnStr) : void 0);
|
|
6845
|
+
if (!dxnRef) {
|
|
6832
6846
|
return;
|
|
6833
6847
|
}
|
|
6834
|
-
const ref = db.makeRef(
|
|
6848
|
+
const ref = db.makeRef(dxnRef);
|
|
6835
6849
|
const target = ref.target;
|
|
6836
6850
|
if (target) {
|
|
6837
6851
|
return Entity.getLabel(target);
|
|
@@ -6849,7 +6863,7 @@ var buildDecorations3 = (state, options, viewRef) => {
|
|
|
6849
6863
|
switch (node.name) {
|
|
6850
6864
|
//
|
|
6851
6865
|
// Inline widget.
|
|
6852
|
-
// [Label](
|
|
6866
|
+
// [Label](echo:/123)
|
|
6853
6867
|
//
|
|
6854
6868
|
case "Link": {
|
|
6855
6869
|
const link = getLinkRef(state, node.node);
|
|
@@ -6868,7 +6882,7 @@ var buildDecorations3 = (state, options, viewRef) => {
|
|
|
6868
6882
|
}
|
|
6869
6883
|
//
|
|
6870
6884
|
// Block widget (transclusion).
|
|
6871
|
-
// 
|
|
6872
6886
|
//
|
|
6873
6887
|
case "Image": {
|
|
6874
6888
|
if (options.addBlockContainer && options.removeBlockContainer) {
|
|
@@ -6892,7 +6906,7 @@ var getLinkRef = (state, node) => {
|
|
|
6892
6906
|
const urlNode = node.getChild("URL");
|
|
6893
6907
|
if (mark && urlNode) {
|
|
6894
6908
|
const dxn = state.sliceDoc(urlNode.from, urlNode.to);
|
|
6895
|
-
if (dxn.startsWith("dxn:")) {
|
|
6909
|
+
if (dxn.startsWith("dxn:") || dxn.startsWith("echo:")) {
|
|
6896
6910
|
const label = state.sliceDoc(mark[0].to, mark[1].from);
|
|
6897
6911
|
return {
|
|
6898
6912
|
block: state.sliceDoc(mark[0].from, mark[0].from + 1) === "!",
|
|
@@ -6936,7 +6950,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6936
6950
|
}
|
|
6937
6951
|
toDOM(_view) {
|
|
6938
6952
|
const root = document.createElement("div");
|
|
6939
|
-
root.classList.add("cm-preview-block", "dx-density-
|
|
6953
|
+
root.classList.add("cm-preview-block", "dx-density-md");
|
|
6940
6954
|
this._options.addBlockContainer?.({
|
|
6941
6955
|
link: this._link,
|
|
6942
6956
|
el: root
|
|
@@ -6952,7 +6966,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6952
6966
|
};
|
|
6953
6967
|
|
|
6954
6968
|
// src/extensions/replacer.ts
|
|
6955
|
-
import { EditorView as
|
|
6969
|
+
import { EditorView as EditorView29 } from "@codemirror/view";
|
|
6956
6970
|
var defaultReplacements = [
|
|
6957
6971
|
{
|
|
6958
6972
|
input: "--",
|
|
@@ -7015,7 +7029,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
7015
7029
|
const sortedReplacements = [
|
|
7016
7030
|
...replacements
|
|
7017
7031
|
].sort((a, b) => b.input.length - a.input.length);
|
|
7018
|
-
return
|
|
7032
|
+
return EditorView29.inputHandler.of((view, from, to, insert) => {
|
|
7019
7033
|
if (insert.length !== 1) {
|
|
7020
7034
|
return false;
|
|
7021
7035
|
}
|
|
@@ -7049,12 +7063,80 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
7049
7063
|
});
|
|
7050
7064
|
};
|
|
7051
7065
|
|
|
7066
|
+
// src/extensions/spacing.ts
|
|
7067
|
+
import { EditorView as EditorView30 } from "@codemirror/view";
|
|
7068
|
+
function lineSpacing(verticalPadding = 2) {
|
|
7069
|
+
return EditorView30.theme({
|
|
7070
|
+
".cm-line": {
|
|
7071
|
+
paddingTop: `${verticalPadding}px`,
|
|
7072
|
+
paddingBottom: `${verticalPadding}px`
|
|
7073
|
+
}
|
|
7074
|
+
});
|
|
7075
|
+
}
|
|
7076
|
+
|
|
7077
|
+
// src/extensions/snippets.ts
|
|
7078
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
7079
|
+
var defaultItems = [
|
|
7080
|
+
"hello world!",
|
|
7081
|
+
"this is a test.",
|
|
7082
|
+
"this is [DXOS](https://dxos.org)"
|
|
7083
|
+
];
|
|
7084
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7085
|
+
let timer;
|
|
7086
|
+
let index = 0;
|
|
7087
|
+
return [
|
|
7088
|
+
keymap12.of([
|
|
7089
|
+
{
|
|
7090
|
+
// Reset.
|
|
7091
|
+
key: "alt-meta-'",
|
|
7092
|
+
run: () => {
|
|
7093
|
+
clearTimeout(timer);
|
|
7094
|
+
index = 0;
|
|
7095
|
+
return true;
|
|
7096
|
+
}
|
|
7097
|
+
},
|
|
7098
|
+
{
|
|
7099
|
+
// Next snippet.
|
|
7100
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
7101
|
+
key: "Shift-Meta-'",
|
|
7102
|
+
run: (view) => {
|
|
7103
|
+
clearTimeout(timer);
|
|
7104
|
+
const text = items[index++];
|
|
7105
|
+
if (index === items?.length) {
|
|
7106
|
+
index = 0;
|
|
7107
|
+
}
|
|
7108
|
+
let offset = 0;
|
|
7109
|
+
const insert = (delayMs = 0) => {
|
|
7110
|
+
timer = setTimeout(() => {
|
|
7111
|
+
const pos = view.state.selection.main.head;
|
|
7112
|
+
view.dispatch({
|
|
7113
|
+
changes: {
|
|
7114
|
+
from: pos,
|
|
7115
|
+
insert: text[offset++]
|
|
7116
|
+
},
|
|
7117
|
+
selection: {
|
|
7118
|
+
anchor: pos + 1
|
|
7119
|
+
}
|
|
7120
|
+
});
|
|
7121
|
+
if (offset < text.length) {
|
|
7122
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
7123
|
+
}
|
|
7124
|
+
}, delayMs);
|
|
7125
|
+
};
|
|
7126
|
+
insert();
|
|
7127
|
+
return true;
|
|
7128
|
+
}
|
|
7129
|
+
}
|
|
7130
|
+
])
|
|
7131
|
+
];
|
|
7132
|
+
};
|
|
7133
|
+
|
|
7052
7134
|
// src/extensions/submit.ts
|
|
7053
7135
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
7054
|
-
import { keymap as
|
|
7136
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
7055
7137
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
7056
7138
|
return [
|
|
7057
|
-
Prec6.highest(
|
|
7139
|
+
Prec6.highest(keymap13.of([
|
|
7058
7140
|
{
|
|
7059
7141
|
key: "Enter",
|
|
7060
7142
|
preventDefault: true,
|
|
@@ -7204,8 +7286,8 @@ var mixedParser = (registry) => {
|
|
|
7204
7286
|
};
|
|
7205
7287
|
|
|
7206
7288
|
// src/extensions/tags/fader.ts
|
|
7207
|
-
import { StateEffect as
|
|
7208
|
-
import { Decoration as Decoration14, EditorView as
|
|
7289
|
+
import { StateEffect as StateEffect11, StateField as StateField12 } from "@codemirror/state";
|
|
7290
|
+
import { Decoration as Decoration14, EditorView as EditorView31, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7209
7291
|
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7210
7292
|
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7211
7293
|
var CLEANUP_INTERVAL = 1e3;
|
|
@@ -7218,7 +7300,7 @@ var fader = (options = {}) => {
|
|
|
7218
7300
|
lastCount = expiries.length;
|
|
7219
7301
|
}
|
|
7220
7302
|
};
|
|
7221
|
-
const dequeue =
|
|
7303
|
+
const dequeue = StateEffect11.define();
|
|
7222
7304
|
const fadeField = StateField12.define({
|
|
7223
7305
|
create: () => ({
|
|
7224
7306
|
decorations: Decoration14.none,
|
|
@@ -7329,9 +7411,9 @@ var fader = (options = {}) => {
|
|
|
7329
7411
|
batchStart
|
|
7330
7412
|
};
|
|
7331
7413
|
},
|
|
7332
|
-
provide: (f) =>
|
|
7414
|
+
provide: (f) => EditorView31.decorations.from(f, (value) => value.decorations)
|
|
7333
7415
|
});
|
|
7334
|
-
const cleanup =
|
|
7416
|
+
const cleanup = ViewPlugin22.fromClass(class {
|
|
7335
7417
|
view;
|
|
7336
7418
|
#timer;
|
|
7337
7419
|
constructor(view) {
|
|
@@ -7366,7 +7448,7 @@ var fader = (options = {}) => {
|
|
|
7366
7448
|
return [
|
|
7367
7449
|
fadeField,
|
|
7368
7450
|
cleanup,
|
|
7369
|
-
|
|
7451
|
+
EditorView31.theme({
|
|
7370
7452
|
".cm-fader": {
|
|
7371
7453
|
animation: "fader 1s ease-out forwards"
|
|
7372
7454
|
},
|
|
@@ -7380,36 +7462,46 @@ var fader = (options = {}) => {
|
|
|
7380
7462
|
];
|
|
7381
7463
|
};
|
|
7382
7464
|
|
|
7383
|
-
// src/extensions/tags/
|
|
7384
|
-
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as
|
|
7385
|
-
import { Decoration as Decoration15, EditorView as
|
|
7465
|
+
// src/extensions/tags/typewriter.ts
|
|
7466
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect12, StateField as StateField13 } from "@codemirror/state";
|
|
7467
|
+
import { Decoration as Decoration15, EditorView as EditorView32, ViewPlugin as ViewPlugin23, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7386
7468
|
import { Domino as Domino3 } from "@dxos/ui";
|
|
7387
|
-
var
|
|
7388
|
-
var
|
|
7469
|
+
var typewriterBypass = Annotation3.define();
|
|
7470
|
+
var typewriterDrainingEffect = StateEffect12.define();
|
|
7389
7471
|
var CURSOR_LINGER = 3e3;
|
|
7390
|
-
var
|
|
7391
|
-
|
|
7392
|
-
|
|
7472
|
+
var FRAME_BUDGET_MS = 4;
|
|
7473
|
+
var CHARS_PER_FRAME = 5;
|
|
7474
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7475
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7476
|
+
var typewriter = (options = {}) => {
|
|
7393
7477
|
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7394
|
-
const
|
|
7395
|
-
const
|
|
7478
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7479
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7480
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7481
|
+
const suppressAppend = StateEffect12.define();
|
|
7482
|
+
const insertChunk = StateEffect12.define();
|
|
7396
7483
|
const bufferField = StateField13.define({
|
|
7397
7484
|
create: () => ({
|
|
7398
7485
|
text: "",
|
|
7486
|
+
head: 0,
|
|
7399
7487
|
insertAt: 0
|
|
7400
7488
|
}),
|
|
7401
7489
|
update: (value, tr) => {
|
|
7402
|
-
let { text, insertAt } = value;
|
|
7490
|
+
let { text, head, insertAt } = value;
|
|
7403
7491
|
for (const effect of tr.effects) {
|
|
7404
7492
|
if (effect.is(suppressAppend)) {
|
|
7405
|
-
text
|
|
7406
|
-
if (text.length === effect.value.text.length) {
|
|
7493
|
+
if (text.length === head) {
|
|
7407
7494
|
insertAt = effect.value.from;
|
|
7408
7495
|
}
|
|
7496
|
+
text += effect.value.text;
|
|
7409
7497
|
}
|
|
7410
7498
|
if (effect.is(insertChunk)) {
|
|
7411
|
-
|
|
7499
|
+
head += effect.value.text.length;
|
|
7412
7500
|
insertAt = effect.value.from + effect.value.text.length;
|
|
7501
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7502
|
+
text = text.slice(head);
|
|
7503
|
+
head = 0;
|
|
7504
|
+
}
|
|
7413
7505
|
}
|
|
7414
7506
|
}
|
|
7415
7507
|
if (tr.docChanged) {
|
|
@@ -7424,6 +7516,7 @@ var wire = (options = {}) => {
|
|
|
7424
7516
|
if (isReset) {
|
|
7425
7517
|
return {
|
|
7426
7518
|
text: "",
|
|
7519
|
+
head: 0,
|
|
7427
7520
|
insertAt: 0
|
|
7428
7521
|
};
|
|
7429
7522
|
}
|
|
@@ -7433,6 +7526,7 @@ var wire = (options = {}) => {
|
|
|
7433
7526
|
}
|
|
7434
7527
|
return {
|
|
7435
7528
|
text,
|
|
7529
|
+
head,
|
|
7436
7530
|
insertAt
|
|
7437
7531
|
};
|
|
7438
7532
|
}
|
|
@@ -7441,7 +7535,7 @@ var wire = (options = {}) => {
|
|
|
7441
7535
|
if (!tr.docChanged) {
|
|
7442
7536
|
return tr;
|
|
7443
7537
|
}
|
|
7444
|
-
if (tr.annotation(
|
|
7538
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7445
7539
|
return tr;
|
|
7446
7540
|
}
|
|
7447
7541
|
let appendedText = "";
|
|
@@ -7468,42 +7562,84 @@ var wire = (options = {}) => {
|
|
|
7468
7562
|
})
|
|
7469
7563
|
};
|
|
7470
7564
|
});
|
|
7471
|
-
const drainPlugin =
|
|
7565
|
+
const drainPlugin = ViewPlugin23.fromClass(class {
|
|
7472
7566
|
view;
|
|
7473
|
-
|
|
7474
|
-
|
|
7567
|
+
_raf;
|
|
7568
|
+
_activeStreamTag = null;
|
|
7475
7569
|
constructor(view) {
|
|
7476
7570
|
this.view = view;
|
|
7477
|
-
this.#start();
|
|
7478
7571
|
}
|
|
7479
7572
|
update(update2) {
|
|
7480
|
-
const
|
|
7481
|
-
|
|
7482
|
-
|
|
7573
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7574
|
+
const pending = text.length - head;
|
|
7575
|
+
if (pending === 0) {
|
|
7576
|
+
this._activeStreamTag = null;
|
|
7483
7577
|
}
|
|
7484
|
-
if (
|
|
7485
|
-
this
|
|
7578
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7579
|
+
this._start();
|
|
7486
7580
|
}
|
|
7487
7581
|
}
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7582
|
+
_start() {
|
|
7583
|
+
queueMicrotask(() => {
|
|
7584
|
+
this.view.dispatch({
|
|
7585
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7586
|
+
annotations: typewriterBypass.of(true)
|
|
7587
|
+
});
|
|
7588
|
+
});
|
|
7589
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7590
|
+
}
|
|
7591
|
+
_tick = () => {
|
|
7592
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7593
|
+
const pending = text.length - head;
|
|
7594
|
+
if (pending === 0) {
|
|
7595
|
+
this.view.dispatch({
|
|
7596
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7597
|
+
annotations: typewriterBypass.of(true)
|
|
7598
|
+
});
|
|
7599
|
+
this._raf = void 0;
|
|
7600
|
+
return;
|
|
7601
|
+
}
|
|
7602
|
+
if (pending > flushThreshold) {
|
|
7603
|
+
const chunk = text.slice(head);
|
|
7604
|
+
this._activeStreamTag = null;
|
|
7605
|
+
this.view.dispatch({
|
|
7606
|
+
changes: {
|
|
7607
|
+
from: insertAt,
|
|
7608
|
+
insert: chunk
|
|
7609
|
+
},
|
|
7610
|
+
effects: insertChunk.of({
|
|
7611
|
+
from: insertAt,
|
|
7612
|
+
text: chunk
|
|
7613
|
+
})
|
|
7614
|
+
});
|
|
7615
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7616
|
+
return;
|
|
7617
|
+
}
|
|
7618
|
+
const startTime = performance.now();
|
|
7619
|
+
let pos = head;
|
|
7620
|
+
let activeTag = this._activeStreamTag;
|
|
7621
|
+
let charsEmitted = 0;
|
|
7622
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7623
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7497
7624
|
if (result.count === 0) {
|
|
7498
|
-
|
|
7625
|
+
break;
|
|
7626
|
+
}
|
|
7627
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7628
|
+
break;
|
|
7499
7629
|
}
|
|
7500
7630
|
if (result.enterTag) {
|
|
7501
|
-
|
|
7631
|
+
activeTag = result.enterTag;
|
|
7502
7632
|
}
|
|
7503
7633
|
if (result.exitTag) {
|
|
7504
|
-
|
|
7634
|
+
activeTag = null;
|
|
7505
7635
|
}
|
|
7506
|
-
|
|
7636
|
+
pos += result.count;
|
|
7637
|
+
charsEmitted += result.count;
|
|
7638
|
+
}
|
|
7639
|
+
const totalCount = pos - head;
|
|
7640
|
+
if (totalCount > 0) {
|
|
7641
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7642
|
+
this._activeStreamTag = activeTag;
|
|
7507
7643
|
this.view.dispatch({
|
|
7508
7644
|
changes: {
|
|
7509
7645
|
from: insertAt,
|
|
@@ -7514,21 +7650,24 @@ var wire = (options = {}) => {
|
|
|
7514
7650
|
text: chunk
|
|
7515
7651
|
})
|
|
7516
7652
|
});
|
|
7517
|
-
}
|
|
7518
|
-
|
|
7653
|
+
}
|
|
7654
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7655
|
+
};
|
|
7519
7656
|
destroy() {
|
|
7520
|
-
|
|
7657
|
+
if (this._raf !== void 0) {
|
|
7658
|
+
cancelAnimationFrame(this._raf);
|
|
7659
|
+
}
|
|
7521
7660
|
}
|
|
7522
7661
|
});
|
|
7523
7662
|
return [
|
|
7524
7663
|
bufferField,
|
|
7525
7664
|
filter,
|
|
7526
7665
|
drainPlugin,
|
|
7527
|
-
options.cursor &&
|
|
7666
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7528
7667
|
].filter(Boolean);
|
|
7529
7668
|
};
|
|
7530
|
-
var
|
|
7531
|
-
const hideCursor =
|
|
7669
|
+
var typewriterCursor = (bufferField) => {
|
|
7670
|
+
const hideCursor = StateEffect12.define();
|
|
7532
7671
|
const visibilityField = StateField13.define({
|
|
7533
7672
|
create: () => ({
|
|
7534
7673
|
visible: false,
|
|
@@ -7536,8 +7675,9 @@ var wireCursor = (bufferField) => {
|
|
|
7536
7675
|
lastNonWsAt: 0
|
|
7537
7676
|
}),
|
|
7538
7677
|
update: (value, tr) => {
|
|
7539
|
-
const { text, insertAt } = tr.state.field(bufferField);
|
|
7540
|
-
|
|
7678
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7679
|
+
const pending = text.length - head;
|
|
7680
|
+
if (pending > 0) {
|
|
7541
7681
|
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7542
7682
|
if (tr.docChanged) {
|
|
7543
7683
|
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
@@ -7571,8 +7711,8 @@ var wireCursor = (bufferField) => {
|
|
|
7571
7711
|
if (!visible) {
|
|
7572
7712
|
return Decoration15.none;
|
|
7573
7713
|
}
|
|
7574
|
-
const { text } = tr.state.field(bufferField);
|
|
7575
|
-
const cursorAt = text.length >
|
|
7714
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7715
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7576
7716
|
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7577
7717
|
return Decoration15.set([
|
|
7578
7718
|
Decoration15.widget({
|
|
@@ -7581,31 +7721,32 @@ var wireCursor = (bufferField) => {
|
|
|
7581
7721
|
}).range(pos)
|
|
7582
7722
|
]);
|
|
7583
7723
|
},
|
|
7584
|
-
provide: (field) =>
|
|
7724
|
+
provide: (field) => EditorView32.decorations.from(field)
|
|
7585
7725
|
});
|
|
7586
|
-
const timerPlugin =
|
|
7726
|
+
const timerPlugin = ViewPlugin23.fromClass(class {
|
|
7587
7727
|
view;
|
|
7588
|
-
|
|
7728
|
+
_timer;
|
|
7589
7729
|
constructor(view) {
|
|
7590
7730
|
this.view = view;
|
|
7591
7731
|
}
|
|
7592
7732
|
update(update2) {
|
|
7593
|
-
const { text } = update2.state.field(bufferField);
|
|
7733
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7594
7734
|
const { visible } = update2.state.field(visibilityField);
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
this
|
|
7598
|
-
|
|
7599
|
-
|
|
7735
|
+
const pending = text.length - head;
|
|
7736
|
+
if (pending > 0) {
|
|
7737
|
+
clearTimeout(this._timer);
|
|
7738
|
+
this._timer = void 0;
|
|
7739
|
+
} else if (visible && this._timer === void 0) {
|
|
7740
|
+
this._timer = setTimeout(() => {
|
|
7600
7741
|
this.view.dispatch({
|
|
7601
7742
|
effects: hideCursor.of(null)
|
|
7602
7743
|
});
|
|
7603
|
-
this
|
|
7744
|
+
this._timer = void 0;
|
|
7604
7745
|
}, CURSOR_LINGER);
|
|
7605
7746
|
}
|
|
7606
7747
|
}
|
|
7607
7748
|
destroy() {
|
|
7608
|
-
clearTimeout(this
|
|
7749
|
+
clearTimeout(this._timer);
|
|
7609
7750
|
}
|
|
7610
7751
|
});
|
|
7611
7752
|
return [
|
|
@@ -7614,7 +7755,12 @@ var wireCursor = (bufferField) => {
|
|
|
7614
7755
|
timerPlugin
|
|
7615
7756
|
];
|
|
7616
7757
|
};
|
|
7617
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7758
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7759
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7760
|
+
// the blink animation isn't restarted on every transaction.
|
|
7761
|
+
eq(other) {
|
|
7762
|
+
return other instanceof _CursorWidget;
|
|
7763
|
+
}
|
|
7618
7764
|
toDOM() {
|
|
7619
7765
|
const inner = Domino3.of("span").text("\u2217").style({
|
|
7620
7766
|
animation: "blink 1s infinite",
|
|
@@ -7626,35 +7772,37 @@ var CursorWidget = class extends WidgetType9 {
|
|
|
7626
7772
|
}
|
|
7627
7773
|
};
|
|
7628
7774
|
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7775
|
+
var TAG_NAME_PROBE = 64;
|
|
7629
7776
|
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7630
|
-
var flushable = (buffer, streamingTags, activeStreamTag) => {
|
|
7631
|
-
if (buffer.length
|
|
7777
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7778
|
+
if (start >= buffer.length) {
|
|
7632
7779
|
return {
|
|
7633
7780
|
count: 0
|
|
7634
7781
|
};
|
|
7635
7782
|
}
|
|
7636
7783
|
if (activeStreamTag) {
|
|
7637
7784
|
const closeTag = `</${activeStreamTag}>`;
|
|
7638
|
-
if (buffer.startsWith(closeTag)) {
|
|
7785
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7639
7786
|
return {
|
|
7640
7787
|
count: closeTag.length,
|
|
7641
7788
|
exitTag: true
|
|
7642
7789
|
};
|
|
7643
7790
|
}
|
|
7644
|
-
if (buffer[
|
|
7791
|
+
if (buffer[start] === "<") {
|
|
7645
7792
|
return {
|
|
7646
|
-
count: xmlElementLength(buffer)
|
|
7793
|
+
count: xmlElementLength(buffer, start)
|
|
7647
7794
|
};
|
|
7648
7795
|
}
|
|
7649
7796
|
return {
|
|
7650
7797
|
count: 1
|
|
7651
7798
|
};
|
|
7652
7799
|
}
|
|
7653
|
-
const ch = buffer[
|
|
7800
|
+
const ch = buffer[start];
|
|
7654
7801
|
if (ch === "<") {
|
|
7655
|
-
const
|
|
7802
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7803
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7656
7804
|
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7657
|
-
const close = buffer.indexOf(">");
|
|
7805
|
+
const close = buffer.indexOf(">", start);
|
|
7658
7806
|
if (close === -1) {
|
|
7659
7807
|
return {
|
|
7660
7808
|
count: 0
|
|
@@ -7662,62 +7810,64 @@ var flushable = (buffer, streamingTags, activeStreamTag) => {
|
|
|
7662
7810
|
}
|
|
7663
7811
|
if (buffer[close - 1] === "/") {
|
|
7664
7812
|
return {
|
|
7665
|
-
count: close + 1
|
|
7813
|
+
count: close + 1 - start
|
|
7666
7814
|
};
|
|
7667
7815
|
}
|
|
7668
7816
|
return {
|
|
7669
|
-
count: close + 1,
|
|
7817
|
+
count: close + 1 - start,
|
|
7670
7818
|
enterTag: nameMatch[1]
|
|
7671
7819
|
};
|
|
7672
7820
|
}
|
|
7673
7821
|
return {
|
|
7674
|
-
count: xmlElementLength(buffer)
|
|
7822
|
+
count: xmlElementLength(buffer, start)
|
|
7675
7823
|
};
|
|
7676
7824
|
}
|
|
7677
|
-
if (ch === "!" && buffer.length > 1 && buffer[1] === "[") {
|
|
7825
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7678
7826
|
return {
|
|
7679
|
-
count: linkLength(buffer, 1)
|
|
7827
|
+
count: linkLength(buffer, start, start + 1)
|
|
7680
7828
|
};
|
|
7681
7829
|
}
|
|
7682
7830
|
if (ch === "[") {
|
|
7683
7831
|
return {
|
|
7684
|
-
count: linkLength(buffer,
|
|
7832
|
+
count: linkLength(buffer, start, start)
|
|
7685
7833
|
};
|
|
7686
7834
|
}
|
|
7687
7835
|
return {
|
|
7688
7836
|
count: 1
|
|
7689
7837
|
};
|
|
7690
7838
|
};
|
|
7691
|
-
var xmlElementLength = (buffer) => {
|
|
7692
|
-
const close = buffer.indexOf(">");
|
|
7839
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7840
|
+
const close = buffer.indexOf(">", start);
|
|
7693
7841
|
if (close === -1) {
|
|
7694
7842
|
return 0;
|
|
7695
7843
|
}
|
|
7696
7844
|
if (buffer[close - 1] === "/") {
|
|
7697
|
-
return close + 1;
|
|
7845
|
+
return close + 1 - start;
|
|
7698
7846
|
}
|
|
7699
|
-
if (buffer[1] === "/") {
|
|
7700
|
-
return close + 1;
|
|
7847
|
+
if (buffer[start + 1] === "/") {
|
|
7848
|
+
return close + 1 - start;
|
|
7701
7849
|
}
|
|
7702
|
-
const
|
|
7850
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7851
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7703
7852
|
if (!nameMatch) {
|
|
7704
7853
|
return 1;
|
|
7705
7854
|
}
|
|
7706
7855
|
const tagName = nameMatch[1];
|
|
7707
7856
|
let depth = 0;
|
|
7708
7857
|
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7858
|
+
tagPattern.lastIndex = start;
|
|
7709
7859
|
let match;
|
|
7710
7860
|
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7711
7861
|
const isSelfClosing = match[0].endsWith("/>");
|
|
7712
7862
|
const isClosing = match[1] === "/";
|
|
7713
7863
|
if (isSelfClosing) {
|
|
7714
7864
|
if (depth === 0) {
|
|
7715
|
-
return match.index + match[0].length;
|
|
7865
|
+
return match.index + match[0].length - start;
|
|
7716
7866
|
}
|
|
7717
7867
|
} else if (isClosing) {
|
|
7718
7868
|
depth--;
|
|
7719
7869
|
if (depth === 0) {
|
|
7720
|
-
return match.index + match[0].length;
|
|
7870
|
+
return match.index + match[0].length - start;
|
|
7721
7871
|
}
|
|
7722
7872
|
} else {
|
|
7723
7873
|
depth++;
|
|
@@ -7725,8 +7875,8 @@ var xmlElementLength = (buffer) => {
|
|
|
7725
7875
|
}
|
|
7726
7876
|
return 0;
|
|
7727
7877
|
};
|
|
7728
|
-
var linkLength = (buffer,
|
|
7729
|
-
const bracketClose = buffer.indexOf("]",
|
|
7878
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7879
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7730
7880
|
if (bracketClose === -1) {
|
|
7731
7881
|
return 0;
|
|
7732
7882
|
}
|
|
@@ -7740,13 +7890,179 @@ var linkLength = (buffer, offset) => {
|
|
|
7740
7890
|
if (parenClose === -1) {
|
|
7741
7891
|
return 0;
|
|
7742
7892
|
}
|
|
7743
|
-
return parenClose + 1;
|
|
7893
|
+
return parenClose + 1 - start;
|
|
7894
|
+
};
|
|
7895
|
+
|
|
7896
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7897
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7898
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin24 } from "@codemirror/view";
|
|
7899
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7900
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7901
|
+
class: lineClass
|
|
7902
|
+
}) : void 0;
|
|
7903
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7904
|
+
class: contentClass
|
|
7905
|
+
}) : void 0;
|
|
7906
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7907
|
+
const buildDecorations5 = (view) => {
|
|
7908
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7909
|
+
if (!text.includes(`<${tag}`)) {
|
|
7910
|
+
return Decoration16.none;
|
|
7911
|
+
}
|
|
7912
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7913
|
+
const ranges = [];
|
|
7914
|
+
tree.iterate({
|
|
7915
|
+
enter: (node) => {
|
|
7916
|
+
if (node.type.name !== "Element") {
|
|
7917
|
+
return;
|
|
7918
|
+
}
|
|
7919
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7920
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7921
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7922
|
+
if (!openTag || !tagNameNode) {
|
|
7923
|
+
return;
|
|
7924
|
+
}
|
|
7925
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7926
|
+
return;
|
|
7927
|
+
}
|
|
7928
|
+
const contentFrom = openTag.to;
|
|
7929
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7930
|
+
if (hideDecoration) {
|
|
7931
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7932
|
+
if (closeTag) {
|
|
7933
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7934
|
+
}
|
|
7935
|
+
}
|
|
7936
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7937
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7938
|
+
}
|
|
7939
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7940
|
+
let pos = contentFrom;
|
|
7941
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7942
|
+
const line = view.state.doc.lineAt(pos);
|
|
7943
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7944
|
+
if (line.to >= contentTo) {
|
|
7945
|
+
break;
|
|
7946
|
+
}
|
|
7947
|
+
pos = line.to + 1;
|
|
7948
|
+
}
|
|
7949
|
+
}
|
|
7950
|
+
}
|
|
7951
|
+
});
|
|
7952
|
+
return Decoration16.set(ranges, true);
|
|
7953
|
+
};
|
|
7954
|
+
return ViewPlugin24.fromClass(class {
|
|
7955
|
+
decorations;
|
|
7956
|
+
constructor(view) {
|
|
7957
|
+
this.decorations = buildDecorations5(view);
|
|
7958
|
+
}
|
|
7959
|
+
update(update2) {
|
|
7960
|
+
if (update2.docChanged) {
|
|
7961
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
}, {
|
|
7965
|
+
decorations: (instance) => instance.decorations
|
|
7966
|
+
});
|
|
7967
|
+
};
|
|
7968
|
+
|
|
7969
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7970
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7971
|
+
import { Decoration as Decoration17, EditorView as EditorView33, ViewPlugin as ViewPlugin25 } from "@codemirror/view";
|
|
7972
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7973
|
+
"OpenTag",
|
|
7974
|
+
"CloseTag",
|
|
7975
|
+
"SelfClosingTag",
|
|
7976
|
+
"MismatchedCloseTag"
|
|
7977
|
+
]);
|
|
7978
|
+
var xmlElementMark = Decoration17.mark({
|
|
7979
|
+
class: "cm-xml-element"
|
|
7980
|
+
});
|
|
7981
|
+
var xmlTagMark = Decoration17.mark({
|
|
7982
|
+
class: "cm-xml-tag"
|
|
7983
|
+
});
|
|
7984
|
+
var xmlContentMark = Decoration17.mark({
|
|
7985
|
+
class: "cm-xml-content"
|
|
7986
|
+
});
|
|
7987
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7988
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7989
|
+
const buildDecorations5 = (view) => {
|
|
7990
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7991
|
+
if (!text.includes("<")) {
|
|
7992
|
+
return Decoration17.none;
|
|
7993
|
+
}
|
|
7994
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7995
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7996
|
+
const ranges = [];
|
|
7997
|
+
tree.iterate({
|
|
7998
|
+
enter: (node) => {
|
|
7999
|
+
const name = node.type.name;
|
|
8000
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
8001
|
+
if (skipSet) {
|
|
8002
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
8003
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
8004
|
+
return false;
|
|
8005
|
+
}
|
|
8006
|
+
}
|
|
8007
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
8008
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
8009
|
+
return;
|
|
8010
|
+
}
|
|
8011
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
8012
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
8013
|
+
return;
|
|
8014
|
+
}
|
|
8015
|
+
if (name === "Element" && node.from < node.to) {
|
|
8016
|
+
const openTag = node.node.getChild("OpenTag");
|
|
8017
|
+
if (openTag && skipSet) {
|
|
8018
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
8019
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
8020
|
+
return false;
|
|
8021
|
+
}
|
|
8022
|
+
}
|
|
8023
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
8024
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
8025
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
8026
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
8027
|
+
}
|
|
8028
|
+
}
|
|
8029
|
+
}
|
|
8030
|
+
});
|
|
8031
|
+
return Decoration17.set(ranges, true);
|
|
8032
|
+
};
|
|
8033
|
+
return [
|
|
8034
|
+
ViewPlugin25.fromClass(class {
|
|
8035
|
+
decorations;
|
|
8036
|
+
constructor(view) {
|
|
8037
|
+
this.decorations = buildDecorations5(view);
|
|
8038
|
+
}
|
|
8039
|
+
update(update2) {
|
|
8040
|
+
if (update2.docChanged) {
|
|
8041
|
+
this.decorations = buildDecorations5(update2.view);
|
|
8042
|
+
}
|
|
8043
|
+
}
|
|
8044
|
+
}, {
|
|
8045
|
+
decorations: (instance) => instance.decorations
|
|
8046
|
+
}),
|
|
8047
|
+
EditorView33.baseTheme({
|
|
8048
|
+
".cm-xml-element": {
|
|
8049
|
+
backgroundColor: "var(--color-current-surface)",
|
|
8050
|
+
borderRadius: "0.25rem",
|
|
8051
|
+
padding: "0.25rem"
|
|
8052
|
+
},
|
|
8053
|
+
".cm-xml-tag": {
|
|
8054
|
+
color: "var(--color-blue-500)",
|
|
8055
|
+
fontFamily: "var(--font-mono)"
|
|
8056
|
+
},
|
|
8057
|
+
".cm-xml-content": {}
|
|
8058
|
+
})
|
|
8059
|
+
];
|
|
7744
8060
|
};
|
|
7745
8061
|
|
|
7746
8062
|
// src/extensions/tags/xml-tags.ts
|
|
7747
8063
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7748
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7749
|
-
import { Decoration as
|
|
8064
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect13, StateField as StateField14 } from "@codemirror/state";
|
|
8065
|
+
import { Decoration as Decoration18, EditorView as EditorView34, ViewPlugin as ViewPlugin26, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7750
8066
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7751
8067
|
import { log as log11 } from "@dxos/log";
|
|
7752
8068
|
import { Domino as Domino4 } from "@dxos/ui";
|
|
@@ -7755,15 +8071,7 @@ import { Domino as Domino4 } from "@dxos/ui";
|
|
|
7755
8071
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7756
8072
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7757
8073
|
var nodeToJson = (state, node) => {
|
|
7758
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7759
|
-
F: __dxlog_file16,
|
|
7760
|
-
L: 18,
|
|
7761
|
-
S: void 0,
|
|
7762
|
-
A: [
|
|
7763
|
-
"node.type.name === 'Element'",
|
|
7764
|
-
"'Node is not an Element'"
|
|
7765
|
-
]
|
|
7766
|
-
});
|
|
8074
|
+
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'"] });
|
|
7767
8075
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7768
8076
|
if (openTag) {
|
|
7769
8077
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7795,13 +8103,23 @@ var nodeToJson = (state, node) => {
|
|
|
7795
8103
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7796
8104
|
const children = [];
|
|
7797
8105
|
let child = node.node.firstChild;
|
|
8106
|
+
const appendText = (raw) => {
|
|
8107
|
+
if (raw.length === 0) {
|
|
8108
|
+
return;
|
|
8109
|
+
}
|
|
8110
|
+
const last = children[children.length - 1];
|
|
8111
|
+
if (typeof last === "string") {
|
|
8112
|
+
children[children.length - 1] = last + raw;
|
|
8113
|
+
} else {
|
|
8114
|
+
children.push(raw);
|
|
8115
|
+
}
|
|
8116
|
+
};
|
|
7798
8117
|
while (child) {
|
|
7799
8118
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7800
8119
|
if (child.type.name === "Text") {
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
}
|
|
8120
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
8121
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
8122
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7805
8123
|
} else if (child.type.name === "Element") {
|
|
7806
8124
|
const data = nodeToJson(state, child);
|
|
7807
8125
|
if (data) {
|
|
@@ -7811,27 +8129,62 @@ var nodeToJson = (state, node) => {
|
|
|
7811
8129
|
}
|
|
7812
8130
|
child = child.nextSibling;
|
|
7813
8131
|
}
|
|
8132
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
8133
|
+
children[0] = children[0].trimStart();
|
|
8134
|
+
}
|
|
7814
8135
|
if (children.length > 0) {
|
|
7815
|
-
|
|
8136
|
+
const lastIndex = children.length - 1;
|
|
8137
|
+
const last = children[lastIndex];
|
|
8138
|
+
if (typeof last === "string") {
|
|
8139
|
+
children[lastIndex] = last.trimEnd();
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
8143
|
+
if (trimmed.length > 0) {
|
|
8144
|
+
tag.children = trimmed;
|
|
7816
8145
|
}
|
|
7817
8146
|
}
|
|
7818
8147
|
return tag;
|
|
7819
8148
|
}
|
|
7820
8149
|
};
|
|
8150
|
+
var XML_NAMED_ENTITIES = {
|
|
8151
|
+
"<": "<",
|
|
8152
|
+
">": ">",
|
|
8153
|
+
"&": "&",
|
|
8154
|
+
""": '"',
|
|
8155
|
+
"'": "'"
|
|
8156
|
+
};
|
|
8157
|
+
var decodeXmlEntity = (raw) => {
|
|
8158
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
8159
|
+
if (named !== void 0) {
|
|
8160
|
+
return named;
|
|
8161
|
+
}
|
|
8162
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
8163
|
+
if (numeric) {
|
|
8164
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
8165
|
+
if (Number.isFinite(code)) {
|
|
8166
|
+
try {
|
|
8167
|
+
return String.fromCodePoint(code);
|
|
8168
|
+
} catch {
|
|
8169
|
+
}
|
|
8170
|
+
}
|
|
8171
|
+
}
|
|
8172
|
+
return raw;
|
|
8173
|
+
};
|
|
7821
8174
|
|
|
7822
8175
|
// src/extensions/tags/xml-tags.ts
|
|
7823
8176
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
7824
|
-
var navigatePreviousEffect =
|
|
7825
|
-
var navigateNextEffect =
|
|
8177
|
+
var navigatePreviousEffect = StateEffect13.define();
|
|
8178
|
+
var navigateNextEffect = StateEffect13.define();
|
|
7826
8179
|
var getXmlTextChild = (children) => {
|
|
7827
8180
|
const child = children?.[0];
|
|
7828
8181
|
return typeof child === "string" ? child : null;
|
|
7829
8182
|
};
|
|
7830
8183
|
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
7831
8184
|
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7832
|
-
var xmlTagContextEffect =
|
|
7833
|
-
var xmlTagResetEffect =
|
|
7834
|
-
var xmlTagUpdateEffect =
|
|
8185
|
+
var xmlTagContextEffect = StateEffect13.define();
|
|
8186
|
+
var xmlTagResetEffect = StateEffect13.define();
|
|
8187
|
+
var xmlTagUpdateEffect = StateEffect13.define();
|
|
7835
8188
|
var widgetContextStateField = StateField14.define({
|
|
7836
8189
|
create: () => void 0,
|
|
7837
8190
|
update: (value, tr) => {
|
|
@@ -7855,12 +8208,7 @@ var widgetStateMapStateField = StateField14.define({
|
|
|
7855
8208
|
log11("widget updated", {
|
|
7856
8209
|
id,
|
|
7857
8210
|
value
|
|
7858
|
-
}, {
|
|
7859
|
-
F: __dxlog_file17,
|
|
7860
|
-
L: 184,
|
|
7861
|
-
S: void 0,
|
|
7862
|
-
C: (f, a) => f(...a)
|
|
7863
|
-
});
|
|
8211
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7864
8212
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7865
8213
|
return {
|
|
7866
8214
|
...map,
|
|
@@ -7871,25 +8219,16 @@ var widgetStateMapStateField = StateField14.define({
|
|
|
7871
8219
|
return map;
|
|
7872
8220
|
}
|
|
7873
8221
|
});
|
|
7874
|
-
var
|
|
7875
|
-
var xmlTags = ({ registry, setWidgets, bookmarks: bookmarks2, paragraphToWidgetGapRem } = {}) => {
|
|
8222
|
+
var xmlTags = ({ registry, setWidgets, bookmarks: bookmarks2 } = {}) => {
|
|
7876
8223
|
const notifier = createWidgetMap(setWidgets);
|
|
7877
8224
|
const widgetDecorationsField = createWidgetDecorationsField(registry, notifier);
|
|
7878
|
-
const paragraphGapTheme = paragraphToWidgetGapRem != null && paragraphToWidgetGapRem > 0 ? EditorView31.baseTheme({
|
|
7879
|
-
[`& .cm-content > .cm-line:not(:has([${XML_WIDGET_DATA_ATTR}])) + .cm-line:has([${XML_WIDGET_DATA_ATTR}])`]: {
|
|
7880
|
-
marginTop: `${paragraphToWidgetGapRem}rem`
|
|
7881
|
-
}
|
|
7882
|
-
}) : null;
|
|
7883
8225
|
return [
|
|
7884
8226
|
widgetContextStateField,
|
|
7885
8227
|
widgetStateMapStateField,
|
|
7886
8228
|
widgetDecorationsField,
|
|
7887
8229
|
createWidgetUpdatePlugin(widgetDecorationsField, notifier),
|
|
7888
8230
|
createNavigationEffectPlugin(widgetDecorationsField, bookmarks2),
|
|
7889
|
-
bookmarks2?.length ? Prec7.highest(keyHandlers) : []
|
|
7890
|
-
...paragraphGapTheme ? [
|
|
7891
|
-
paragraphGapTheme
|
|
7892
|
-
] : []
|
|
8231
|
+
bookmarks2?.length ? Prec7.highest(keyHandlers) : []
|
|
7893
8232
|
];
|
|
7894
8233
|
};
|
|
7895
8234
|
var createWidgetMap = (setWidgets) => {
|
|
@@ -7899,12 +8238,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7899
8238
|
log11("widget mounted", {
|
|
7900
8239
|
id: state.id,
|
|
7901
8240
|
tag: state.props._tag
|
|
7902
|
-
}, {
|
|
7903
|
-
F: __dxlog_file17,
|
|
7904
|
-
L: 261,
|
|
7905
|
-
S: void 0,
|
|
7906
|
-
C: (f, a) => f(...a)
|
|
7907
|
-
});
|
|
8241
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7908
8242
|
widgets.set(state.id, state);
|
|
7909
8243
|
setWidgets?.([
|
|
7910
8244
|
...widgets.values()
|
|
@@ -7915,12 +8249,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7915
8249
|
log11("widget unmounted", {
|
|
7916
8250
|
id,
|
|
7917
8251
|
tag: state?.props._tag
|
|
7918
|
-
}, {
|
|
7919
|
-
F: __dxlog_file17,
|
|
7920
|
-
L: 267,
|
|
7921
|
-
S: void 0,
|
|
7922
|
-
C: (f, a) => f(...a)
|
|
7923
|
-
});
|
|
8252
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7924
8253
|
widgets.delete(id);
|
|
7925
8254
|
setWidgets?.([
|
|
7926
8255
|
...widgets.values()
|
|
@@ -7929,7 +8258,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7929
8258
|
};
|
|
7930
8259
|
return notifier;
|
|
7931
8260
|
};
|
|
7932
|
-
var keyHandlers =
|
|
8261
|
+
var keyHandlers = keymap14.of([
|
|
7933
8262
|
{
|
|
7934
8263
|
key: "Mod-ArrowUp",
|
|
7935
8264
|
run: (view) => {
|
|
@@ -7950,7 +8279,7 @@ var keyHandlers = keymap13.of([
|
|
|
7950
8279
|
}
|
|
7951
8280
|
]);
|
|
7952
8281
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7953
|
-
return
|
|
8282
|
+
return EditorView34.updateListener.of((update2) => {
|
|
7954
8283
|
update2.transactions.forEach((transaction) => {
|
|
7955
8284
|
for (const effect of transaction.effects) {
|
|
7956
8285
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7978,7 +8307,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7978
8307
|
anchor: line.from,
|
|
7979
8308
|
head: line.from
|
|
7980
8309
|
},
|
|
7981
|
-
effects:
|
|
8310
|
+
effects: crawlerLineEffect.of({
|
|
7982
8311
|
line: line.number - 1,
|
|
7983
8312
|
offset: -16
|
|
7984
8313
|
})
|
|
@@ -8011,7 +8340,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8011
8340
|
anchor: line.to,
|
|
8012
8341
|
head: line.to
|
|
8013
8342
|
},
|
|
8014
|
-
effects:
|
|
8343
|
+
effects: crawlerLineEffect.of({
|
|
8015
8344
|
line: line.number - 1,
|
|
8016
8345
|
offset: -16
|
|
8017
8346
|
})
|
|
@@ -8023,7 +8352,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8023
8352
|
anchor: line.to,
|
|
8024
8353
|
head: line.to
|
|
8025
8354
|
},
|
|
8026
|
-
effects:
|
|
8355
|
+
effects: crawlerLineEffect.of({
|
|
8027
8356
|
line: line.number - 1,
|
|
8028
8357
|
position: "end"
|
|
8029
8358
|
})
|
|
@@ -8035,7 +8364,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8035
8364
|
});
|
|
8036
8365
|
});
|
|
8037
8366
|
};
|
|
8038
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8367
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin26.fromClass(class {
|
|
8039
8368
|
update(update2) {
|
|
8040
8369
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
8041
8370
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -8080,7 +8409,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8080
8409
|
}
|
|
8081
8410
|
return {
|
|
8082
8411
|
from: 0,
|
|
8083
|
-
decorations:
|
|
8412
|
+
decorations: Decoration18.none
|
|
8084
8413
|
};
|
|
8085
8414
|
}
|
|
8086
8415
|
}
|
|
@@ -8091,12 +8420,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8091
8420
|
log11("document reset", {
|
|
8092
8421
|
from,
|
|
8093
8422
|
to: state.doc.length
|
|
8094
|
-
}, {
|
|
8095
|
-
F: __dxlog_file17,
|
|
8096
|
-
L: 429,
|
|
8097
|
-
S: void 0,
|
|
8098
|
-
C: (f, a) => f(...a)
|
|
8099
|
-
});
|
|
8423
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
8100
8424
|
return buildDecorations4(state, {
|
|
8101
8425
|
from: 0,
|
|
8102
8426
|
to: state.doc.length
|
|
@@ -8125,8 +8449,8 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8125
8449
|
};
|
|
8126
8450
|
},
|
|
8127
8451
|
provide: (field) => [
|
|
8128
|
-
|
|
8129
|
-
|
|
8452
|
+
EditorView34.decorations.from(field, (v) => v.decorations),
|
|
8453
|
+
EditorView34.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
8130
8454
|
]
|
|
8131
8455
|
});
|
|
8132
8456
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -8137,7 +8461,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8137
8461
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
8138
8462
|
return {
|
|
8139
8463
|
from: range.from,
|
|
8140
|
-
decorations:
|
|
8464
|
+
decorations: Decoration18.none
|
|
8141
8465
|
};
|
|
8142
8466
|
}
|
|
8143
8467
|
let last = range.from;
|
|
@@ -8173,7 +8497,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8173
8497
|
};
|
|
8174
8498
|
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
8175
8499
|
if (widget) {
|
|
8176
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8500
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
8177
8501
|
widget,
|
|
8178
8502
|
block,
|
|
8179
8503
|
atomic: true,
|
|
@@ -8185,12 +8509,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8185
8509
|
}
|
|
8186
8510
|
}
|
|
8187
8511
|
} catch (err) {
|
|
8188
|
-
log11.catch(err, void 0, {
|
|
8189
|
-
F: __dxlog_file17,
|
|
8190
|
-
L: 538,
|
|
8191
|
-
S: void 0,
|
|
8192
|
-
C: (f, a) => f(...a)
|
|
8193
|
-
});
|
|
8512
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
8194
8513
|
}
|
|
8195
8514
|
return false;
|
|
8196
8515
|
}
|
|
@@ -8237,7 +8556,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8237
8556
|
};
|
|
8238
8557
|
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8239
8558
|
if (widget) {
|
|
8240
|
-
builder.add(absoluteFrom, range.to,
|
|
8559
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8241
8560
|
widget,
|
|
8242
8561
|
block: def.block,
|
|
8243
8562
|
atomic: true,
|
|
@@ -8269,15 +8588,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8269
8588
|
#view;
|
|
8270
8589
|
constructor(id, Component, props, notifier, streaming) {
|
|
8271
8590
|
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8272
|
-
invariant7(id, void 0, {
|
|
8273
|
-
F: __dxlog_file17,
|
|
8274
|
-
L: 641,
|
|
8275
|
-
S: this,
|
|
8276
|
-
A: [
|
|
8277
|
-
"id",
|
|
8278
|
-
""
|
|
8279
|
-
]
|
|
8280
|
-
});
|
|
8591
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
8281
8592
|
}
|
|
8282
8593
|
get root() {
|
|
8283
8594
|
return this.#root;
|
|
@@ -8293,9 +8604,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8293
8604
|
}
|
|
8294
8605
|
toDOM(view) {
|
|
8295
8606
|
this.#view = view;
|
|
8296
|
-
this.#root = Domino4.of("div").classNames("min-h-[24px]").
|
|
8297
|
-
[XML_WIDGET_DATA_ATTR]: ""
|
|
8298
|
-
}).root;
|
|
8607
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8299
8608
|
const props = Object.assign({}, this.props, {
|
|
8300
8609
|
view
|
|
8301
8610
|
});
|
|
@@ -8326,71 +8635,10 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8326
8635
|
this.#view = void 0;
|
|
8327
8636
|
}
|
|
8328
8637
|
};
|
|
8329
|
-
|
|
8330
|
-
// src/extensions/typewriter.ts
|
|
8331
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
8332
|
-
var defaultItems = [
|
|
8333
|
-
"hello world!",
|
|
8334
|
-
"this is a test.",
|
|
8335
|
-
"this is [DXOS](https://dxos.org)"
|
|
8336
|
-
];
|
|
8337
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
8338
|
-
let t;
|
|
8339
|
-
let idx = 0;
|
|
8340
|
-
return [
|
|
8341
|
-
keymap14.of([
|
|
8342
|
-
{
|
|
8343
|
-
// Reset.
|
|
8344
|
-
key: "alt-meta-'",
|
|
8345
|
-
run: () => {
|
|
8346
|
-
clearTimeout(t);
|
|
8347
|
-
idx = 0;
|
|
8348
|
-
return true;
|
|
8349
|
-
}
|
|
8350
|
-
},
|
|
8351
|
-
{
|
|
8352
|
-
// Next prompt.
|
|
8353
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
8354
|
-
key: "Shift-Meta-'",
|
|
8355
|
-
run: (view) => {
|
|
8356
|
-
clearTimeout(t);
|
|
8357
|
-
const text = items[idx++];
|
|
8358
|
-
if (idx === items?.length) {
|
|
8359
|
-
idx = 0;
|
|
8360
|
-
}
|
|
8361
|
-
let i = 0;
|
|
8362
|
-
const insert = (d = 0) => {
|
|
8363
|
-
t = setTimeout(() => {
|
|
8364
|
-
const pos = view.state.selection.main.head;
|
|
8365
|
-
view.dispatch({
|
|
8366
|
-
changes: {
|
|
8367
|
-
from: pos,
|
|
8368
|
-
insert: text[i++]
|
|
8369
|
-
},
|
|
8370
|
-
selection: {
|
|
8371
|
-
anchor: pos + 1
|
|
8372
|
-
}
|
|
8373
|
-
});
|
|
8374
|
-
if (i < text.length) {
|
|
8375
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
8376
|
-
}
|
|
8377
|
-
}, d);
|
|
8378
|
-
};
|
|
8379
|
-
insert();
|
|
8380
|
-
return true;
|
|
8381
|
-
}
|
|
8382
|
-
}
|
|
8383
|
-
])
|
|
8384
|
-
];
|
|
8385
|
-
};
|
|
8386
8638
|
export {
|
|
8387
8639
|
Cursor,
|
|
8388
|
-
EditorInputMode,
|
|
8389
|
-
EditorInputModes,
|
|
8390
8640
|
EditorState4 as EditorState,
|
|
8391
|
-
|
|
8392
|
-
EditorViewMode,
|
|
8393
|
-
EditorViewModes,
|
|
8641
|
+
EditorView35 as EditorView,
|
|
8394
8642
|
Inline,
|
|
8395
8643
|
InputModeExtensions,
|
|
8396
8644
|
List,
|
|
@@ -8399,7 +8647,6 @@ export {
|
|
|
8399
8647
|
SpaceAwarenessProvider,
|
|
8400
8648
|
TextKind,
|
|
8401
8649
|
Tree,
|
|
8402
|
-
XML_WIDGET_DATA_ATTR,
|
|
8403
8650
|
addBlockquote,
|
|
8404
8651
|
addBookmark,
|
|
8405
8652
|
addCodeblock,
|
|
@@ -8424,6 +8671,9 @@ export {
|
|
|
8424
8671
|
commentsState,
|
|
8425
8672
|
compactSlots,
|
|
8426
8673
|
convertTreeToJson,
|
|
8674
|
+
crawler,
|
|
8675
|
+
crawlerActiveEffect,
|
|
8676
|
+
crawlerLineEffect,
|
|
8427
8677
|
createBasicExtensions,
|
|
8428
8678
|
createComment,
|
|
8429
8679
|
createCrawler,
|
|
@@ -8475,9 +8725,11 @@ export {
|
|
|
8475
8725
|
insertAtCursor,
|
|
8476
8726
|
insertAtLineStart,
|
|
8477
8727
|
insertTable,
|
|
8728
|
+
isRangeVisible,
|
|
8478
8729
|
itemToJSON,
|
|
8479
8730
|
join,
|
|
8480
8731
|
keymap15 as keymap,
|
|
8732
|
+
lineSpacing,
|
|
8481
8733
|
linkTooltip,
|
|
8482
8734
|
listItemToString,
|
|
8483
8735
|
listener,
|
|
@@ -8510,9 +8762,8 @@ export {
|
|
|
8510
8762
|
scrollPastEnd,
|
|
8511
8763
|
scrollThreadIntoView,
|
|
8512
8764
|
scrollToLine,
|
|
8765
|
+
scrollbarAutohide,
|
|
8513
8766
|
scroller,
|
|
8514
|
-
scrollerCrawlEffect,
|
|
8515
|
-
scrollerLineEffect,
|
|
8516
8767
|
selectionState,
|
|
8517
8768
|
setBlockquote,
|
|
8518
8769
|
setComments,
|
|
@@ -8520,6 +8771,7 @@ export {
|
|
|
8520
8771
|
setSelection,
|
|
8521
8772
|
setStyle,
|
|
8522
8773
|
singleValueFacet,
|
|
8774
|
+
snippets2 as snippets,
|
|
8523
8775
|
staticCompletion,
|
|
8524
8776
|
submit,
|
|
8525
8777
|
tabbable,
|
|
@@ -8539,10 +8791,12 @@ export {
|
|
|
8539
8791
|
treeFacet,
|
|
8540
8792
|
typeahead,
|
|
8541
8793
|
typewriter,
|
|
8542
|
-
|
|
8543
|
-
|
|
8794
|
+
typewriterBypass,
|
|
8795
|
+
typewriterDrainingEffect,
|
|
8544
8796
|
wrapWithCatch,
|
|
8797
|
+
xmlBlockDecoration,
|
|
8545
8798
|
xmlElementLength,
|
|
8799
|
+
xmlFormatting,
|
|
8546
8800
|
xmlTagContextEffect,
|
|
8547
8801
|
xmlTagResetEffect,
|
|
8548
8802
|
xmlTagUpdateEffect,
|