@dxos/ui-editor 0.8.4-main.9be5663bfe → 0.8.4-main.bc2380dfbc
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 +995 -879
- 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 +995 -878
- 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 +1 -0
- 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.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +2 -1
- 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 +2 -4
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/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.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 +75 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/index.d.ts +5 -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/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/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 +4 -4
- 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 +33 -36
- package/src/defaults.ts +12 -3
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +35 -9
- package/src/extensions/automerge/automerge.ts +2 -4
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +25 -6
- package/src/extensions/index.ts +2 -4
- package/src/extensions/outliner/outliner.ts +1 -1
- package/src/extensions/{auto-scroll.ts → scrolling/auto-scroll.ts} +88 -23
- package/src/extensions/{scroller.ts → scrolling/crawler.ts} +63 -45
- package/src/extensions/scrolling/index.ts +8 -0
- package/src/extensions/{scroll-past-end.ts → scrolling/scroll-past-end.ts} +6 -6
- package/src/extensions/scrolling/scroller.ts +27 -0
- package/src/extensions/snippets.ts +67 -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 +20 -10
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/dist/lib/browser/chunk-HL3YF6WC.mjs +0 -22
- package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs +0 -24
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +0 -7
- package/dist/types/src/extensions/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/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,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EditorInputMode,
|
|
3
|
-
EditorInputModes,
|
|
4
|
-
EditorViewMode,
|
|
5
|
-
EditorViewModes
|
|
6
|
-
} from "./chunk-HL3YF6WC.mjs";
|
|
7
|
-
|
|
8
1
|
// src/index.ts
|
|
9
2
|
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
10
|
-
import { EditorView as
|
|
3
|
+
import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
|
|
11
4
|
import { tags as tags2 } from "@lezer/highlight";
|
|
12
5
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
13
6
|
|
|
@@ -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"
|
|
@@ -33,7 +29,12 @@ var documentSlots = {
|
|
|
33
29
|
};
|
|
34
30
|
var compactSlots = {
|
|
35
31
|
content: {
|
|
36
|
-
className: "mx-2!
|
|
32
|
+
className: "mx-2!"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var mobileSlots = {
|
|
36
|
+
content: {
|
|
37
|
+
className: "mx-2!"
|
|
37
38
|
}
|
|
38
39
|
};
|
|
39
40
|
|
|
@@ -270,12 +271,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
270
271
|
} catch (err) {
|
|
271
272
|
log.catch(err, {
|
|
272
273
|
label
|
|
273
|
-
}, {
|
|
274
|
-
F: __dxlog_file,
|
|
275
|
-
L: 20,
|
|
276
|
-
S: void 0,
|
|
277
|
-
C: (f, a) => f(...a)
|
|
278
|
-
});
|
|
274
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
279
275
|
}
|
|
280
276
|
};
|
|
281
277
|
};
|
|
@@ -301,12 +297,7 @@ var logChanges = (trs) => {
|
|
|
301
297
|
if (changes.length) {
|
|
302
298
|
log("changes", {
|
|
303
299
|
changes
|
|
304
|
-
}, {
|
|
305
|
-
F: __dxlog_file,
|
|
306
|
-
L: 54,
|
|
307
|
-
S: void 0,
|
|
308
|
-
C: (f, a) => f(...a)
|
|
309
|
-
});
|
|
300
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
310
301
|
}
|
|
311
302
|
};
|
|
312
303
|
|
|
@@ -372,30 +363,37 @@ var insertAtLineStart = (view, from, insert) => {
|
|
|
372
363
|
};
|
|
373
364
|
|
|
374
365
|
// src/extensions/autocomplete/placeholder.ts
|
|
375
|
-
var placeholder = ({ content, delay = 3e3 }) => {
|
|
366
|
+
var placeholder = ({ content, delay = 3e3, focusOnly = false }) => {
|
|
376
367
|
const plugin = ViewPlugin3.fromClass(class {
|
|
377
368
|
_timeout;
|
|
378
369
|
_decorations = Decoration3.none;
|
|
379
370
|
update(update2) {
|
|
371
|
+
if (!update2.docChanged && !update2.selectionSet && !update2.focusChanged) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
380
374
|
if (this._timeout) {
|
|
381
375
|
window.clearTimeout(this._timeout);
|
|
382
376
|
this._timeout = void 0;
|
|
383
377
|
}
|
|
378
|
+
this._decorations = Decoration3.none;
|
|
379
|
+
if (focusOnly && !update2.view.hasFocus) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
384
382
|
const activeLine = update2.view.state.doc.lineAt(update2.view.state.selection.main.head);
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const lineStart = activeLine.from;
|
|
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
|
-
update2.view.update([]);
|
|
396
|
-
}, delay);
|
|
383
|
+
if (activeLine.text.trim() !== "") {
|
|
384
|
+
return;
|
|
397
385
|
}
|
|
398
|
-
|
|
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);
|
|
399
397
|
}
|
|
400
398
|
destroy() {
|
|
401
399
|
if (this._timeout) {
|
|
@@ -513,300 +511,10 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
513
511
|
];
|
|
514
512
|
};
|
|
515
513
|
|
|
516
|
-
// src/extensions/auto-scroll.ts
|
|
517
|
-
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
518
|
-
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
519
|
-
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
520
|
-
import { Domino } from "@dxos/ui";
|
|
521
|
-
import { getSize } from "@dxos/ui-theme";
|
|
522
|
-
|
|
523
|
-
// src/extensions/scroller.ts
|
|
524
|
-
import { StateEffect } from "@codemirror/state";
|
|
525
|
-
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
526
|
-
import { log as log2 } from "@dxos/log";
|
|
527
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scroller.ts";
|
|
528
|
-
var scrollerLineEffect = StateEffect.define();
|
|
529
|
-
var scrollerCrawlEffect = StateEffect.define();
|
|
530
|
-
var scrollToLine = (view, options) => {
|
|
531
|
-
view.dispatch({
|
|
532
|
-
effects: scrollerLineEffect.of(options)
|
|
533
|
-
});
|
|
534
|
-
};
|
|
535
|
-
var scroller = ({ overScroll = 0 } = {}) => {
|
|
536
|
-
const scrollPlugin = ViewPlugin5.fromClass(class ScrollerPlugin {
|
|
537
|
-
view;
|
|
538
|
-
crawler;
|
|
539
|
-
constructor(view) {
|
|
540
|
-
this.view = view;
|
|
541
|
-
this.crawler = createCrawler(this.view);
|
|
542
|
-
}
|
|
543
|
-
// No-op.
|
|
544
|
-
destroy() {
|
|
545
|
-
this.crawler.cancel();
|
|
546
|
-
}
|
|
547
|
-
cancel() {
|
|
548
|
-
this.crawler.cancel();
|
|
549
|
-
}
|
|
550
|
-
crawl(start = false) {
|
|
551
|
-
if (start) {
|
|
552
|
-
this.crawler.scroll();
|
|
553
|
-
} else {
|
|
554
|
-
this.crawler.cancel();
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
558
|
-
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
559
|
-
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
560
|
-
const doc = this.view.state.doc;
|
|
561
|
-
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
562
|
-
if (line >= 0 && line <= doc.lines - 1) {
|
|
563
|
-
const lineStart = doc.line(line + 1).from;
|
|
564
|
-
const coords = this.view.coordsAtPos(lineStart);
|
|
565
|
-
if (coords) {
|
|
566
|
-
const currentScrollTop = scrollTop;
|
|
567
|
-
const maxScrollTop = scrollHeight - clientHeight;
|
|
568
|
-
if (position === "end") {
|
|
569
|
-
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
570
|
-
} else {
|
|
571
|
-
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
572
|
-
}
|
|
573
|
-
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
requestAnimationFrame(() => {
|
|
577
|
-
this.view.scrollDOM.scrollTo({
|
|
578
|
-
top: targetScrollTop
|
|
579
|
-
});
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
return [
|
|
584
|
-
scrollPlugin,
|
|
585
|
-
// Listen for effect.s
|
|
586
|
-
EditorView4.updateListener.of((update2) => {
|
|
587
|
-
update2.transactions.forEach((transaction) => {
|
|
588
|
-
try {
|
|
589
|
-
const plugin = update2.view.plugin(scrollPlugin);
|
|
590
|
-
if (plugin) {
|
|
591
|
-
for (const effect of transaction.effects) {
|
|
592
|
-
if (effect.is(scrollerCrawlEffect)) {
|
|
593
|
-
plugin.crawl(effect.value);
|
|
594
|
-
} else if (effect.is(scrollerLineEffect)) {
|
|
595
|
-
plugin.scroll(effect.value);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
} catch (err) {
|
|
600
|
-
log2.catch(err, void 0, {
|
|
601
|
-
F: __dxlog_file2,
|
|
602
|
-
L: 146,
|
|
603
|
-
S: void 0,
|
|
604
|
-
C: (f, a) => f(...a)
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
});
|
|
608
|
-
}),
|
|
609
|
-
// Styles.
|
|
610
|
-
EditorView4.theme({
|
|
611
|
-
".cm-content": {
|
|
612
|
-
paddingBottom: `${overScroll}px`
|
|
613
|
-
},
|
|
614
|
-
".cm-scroller": {
|
|
615
|
-
overflowY: "scroll",
|
|
616
|
-
overflowAnchor: "none",
|
|
617
|
-
paddingBottom: "0"
|
|
618
|
-
},
|
|
619
|
-
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
620
|
-
display: "none"
|
|
621
|
-
},
|
|
622
|
-
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
623
|
-
background: "transparent",
|
|
624
|
-
transition: "background 0.15s"
|
|
625
|
-
},
|
|
626
|
-
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
627
|
-
background: "var(--color-scrollbar-thumb)"
|
|
628
|
-
},
|
|
629
|
-
".cm-scroll-button": {
|
|
630
|
-
position: "absolute",
|
|
631
|
-
bottom: "0.5rem",
|
|
632
|
-
right: "1rem"
|
|
633
|
-
}
|
|
634
|
-
})
|
|
635
|
-
];
|
|
636
|
-
};
|
|
637
|
-
function createCrawler(view, accel = 0.15, maxVelocity = 1, snapThreshold = 0.5) {
|
|
638
|
-
const el = view.scrollDOM;
|
|
639
|
-
let currentTop = 0;
|
|
640
|
-
let velocity = 0;
|
|
641
|
-
let rafId = null;
|
|
642
|
-
function frame() {
|
|
643
|
-
const targetTop = el.scrollHeight - el.clientHeight;
|
|
644
|
-
const delta = targetTop - currentTop;
|
|
645
|
-
const absDelta = Math.abs(delta);
|
|
646
|
-
if (absDelta < snapThreshold && Math.abs(velocity) < snapThreshold) {
|
|
647
|
-
el.scrollTop = targetTop;
|
|
648
|
-
currentTop = targetTop;
|
|
649
|
-
velocity = 0;
|
|
650
|
-
rafId = null;
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
const stoppingDistance = velocity * velocity / (2 * accel);
|
|
654
|
-
const direction = Math.sign(delta);
|
|
655
|
-
if (velocity !== 0 && (absDelta <= stoppingDistance || direction !== Math.sign(velocity))) {
|
|
656
|
-
velocity -= Math.sign(velocity) * Math.min(accel, Math.abs(velocity));
|
|
657
|
-
} else {
|
|
658
|
-
velocity += direction * accel;
|
|
659
|
-
velocity = Math.sign(velocity) * Math.min(Math.abs(velocity), maxVelocity);
|
|
660
|
-
}
|
|
661
|
-
currentTop += velocity;
|
|
662
|
-
el.scrollTop = currentTop;
|
|
663
|
-
rafId = requestAnimationFrame(frame);
|
|
664
|
-
}
|
|
665
|
-
return {
|
|
666
|
-
scroll: () => {
|
|
667
|
-
if (rafId === null) {
|
|
668
|
-
currentTop = el.scrollTop;
|
|
669
|
-
rafId = requestAnimationFrame(frame);
|
|
670
|
-
}
|
|
671
|
-
},
|
|
672
|
-
cancel: () => {
|
|
673
|
-
if (rafId !== null) {
|
|
674
|
-
cancelAnimationFrame(rafId);
|
|
675
|
-
rafId = null;
|
|
676
|
-
velocity = 0;
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
// src/extensions/auto-scroll.ts
|
|
683
|
-
var autoScrollEffect = StateEffect2.define();
|
|
684
|
-
var autoScroll = (_ = {}) => {
|
|
685
|
-
let buttonContainer;
|
|
686
|
-
let isPinned = true;
|
|
687
|
-
let jumpPending = false;
|
|
688
|
-
let enabled = true;
|
|
689
|
-
let firstUpdate = true;
|
|
690
|
-
const setPinned = (pinned) => {
|
|
691
|
-
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
692
|
-
isPinned = pinned;
|
|
693
|
-
};
|
|
694
|
-
return [
|
|
695
|
-
// Update listener for scrolling when content changes.
|
|
696
|
-
EditorView5.updateListener.of((update2) => {
|
|
697
|
-
const { view, heightChanged, state, startState } = update2;
|
|
698
|
-
for (const tr of update2.transactions) {
|
|
699
|
-
for (const effect of tr.effects) {
|
|
700
|
-
if (effect.is(autoScrollEffect)) {
|
|
701
|
-
enabled = effect.value;
|
|
702
|
-
if (enabled) {
|
|
703
|
-
setPinned(true);
|
|
704
|
-
view.dispatch({
|
|
705
|
-
effects: scrollerCrawlEffect.of(true)
|
|
706
|
-
});
|
|
707
|
-
} else {
|
|
708
|
-
view.dispatch({
|
|
709
|
-
effects: scrollerCrawlEffect.of(false)
|
|
710
|
-
});
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
if (!enabled) {
|
|
716
|
-
return;
|
|
717
|
-
}
|
|
718
|
-
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
719
|
-
firstUpdate = false;
|
|
720
|
-
jumpPending = true;
|
|
721
|
-
requestAnimationFrame(() => {
|
|
722
|
-
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
723
|
-
jumpPending = false;
|
|
724
|
-
});
|
|
725
|
-
return;
|
|
726
|
-
}
|
|
727
|
-
firstUpdate = false;
|
|
728
|
-
if (jumpPending) {
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
if (heightChanged) {
|
|
732
|
-
if (isPinned) {
|
|
733
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
734
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
735
|
-
if (delta > 0) {
|
|
736
|
-
setPinned(true);
|
|
737
|
-
view.dispatch({
|
|
738
|
-
effects: scrollerCrawlEffect.of(true)
|
|
739
|
-
});
|
|
740
|
-
} else if (delta < -1) {
|
|
741
|
-
setPinned(false);
|
|
742
|
-
}
|
|
743
|
-
} else {
|
|
744
|
-
if (state.doc.length === 0) {
|
|
745
|
-
setPinned(true);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
}),
|
|
750
|
-
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
751
|
-
ViewPlugin6.fromClass(class {
|
|
752
|
-
cleanup;
|
|
753
|
-
constructor(view) {
|
|
754
|
-
this.cleanup = createUserScrollDetector(view.scrollDOM, throttle(() => {
|
|
755
|
-
requestAnimationFrame(() => {
|
|
756
|
-
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
757
|
-
const delta = scrollHeight - scrollTop - clientHeight;
|
|
758
|
-
const pinned = delta === 0;
|
|
759
|
-
setPinned(pinned);
|
|
760
|
-
if (!pinned) {
|
|
761
|
-
view.dispatch({
|
|
762
|
-
effects: scrollerCrawlEffect.of(false)
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
});
|
|
766
|
-
}, 500));
|
|
767
|
-
}
|
|
768
|
-
destroy() {
|
|
769
|
-
this.cleanup();
|
|
770
|
-
}
|
|
771
|
-
}),
|
|
772
|
-
// Scroll button.
|
|
773
|
-
ViewPlugin6.fromClass(class {
|
|
774
|
-
constructor(view) {
|
|
775
|
-
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
776
|
-
icon: "ph--arrow-down--regular"
|
|
777
|
-
});
|
|
778
|
-
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
779
|
-
"data-density": "fine"
|
|
780
|
-
}).append(icon).on("click", () => {
|
|
781
|
-
setPinned(true);
|
|
782
|
-
view.dispatch({
|
|
783
|
-
effects: scrollerLineEffect.of({
|
|
784
|
-
line: -1,
|
|
785
|
-
position: "end",
|
|
786
|
-
behavior: "smooth"
|
|
787
|
-
})
|
|
788
|
-
});
|
|
789
|
-
});
|
|
790
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
791
|
-
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
792
|
-
}
|
|
793
|
-
})
|
|
794
|
-
];
|
|
795
|
-
};
|
|
796
|
-
function createUserScrollDetector(element, onUserScroll) {
|
|
797
|
-
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
798
|
-
passive: true
|
|
799
|
-
}), addEventListener(element, "pointerdown", (event) => {
|
|
800
|
-
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
801
|
-
onUserScroll();
|
|
802
|
-
}
|
|
803
|
-
}));
|
|
804
|
-
}
|
|
805
|
-
|
|
806
514
|
// src/extensions/automerge/automerge.ts
|
|
807
515
|
import { next as A3 } from "@automerge/automerge";
|
|
808
516
|
import { StateField, Transaction as Transaction2 } from "@codemirror/state";
|
|
809
|
-
import { EditorView as
|
|
517
|
+
import { EditorView as EditorView4, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
810
518
|
import { DocAccessor } from "@dxos/echo-db";
|
|
811
519
|
|
|
812
520
|
// src/extensions/state.ts
|
|
@@ -815,19 +523,14 @@ var initialSync = Transaction.userEvent.of("initial.sync");
|
|
|
815
523
|
|
|
816
524
|
// src/extensions/automerge/cursor.ts
|
|
817
525
|
import { fromCursor, toCursor } from "@dxos/echo-db";
|
|
818
|
-
import { log as
|
|
819
|
-
var
|
|
526
|
+
import { log as log2 } from "@dxos/log";
|
|
527
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/cursor.ts";
|
|
820
528
|
var cursorConverter = (accessor) => ({
|
|
821
529
|
toCursor: (pos, assoc) => {
|
|
822
530
|
try {
|
|
823
531
|
return toCursor(accessor, pos, assoc);
|
|
824
532
|
} catch (err) {
|
|
825
|
-
|
|
826
|
-
F: __dxlog_file3,
|
|
827
|
-
L: 15,
|
|
828
|
-
S: void 0,
|
|
829
|
-
C: (f, a) => f(...a)
|
|
830
|
-
});
|
|
533
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 11, S: void 0 });
|
|
831
534
|
return "";
|
|
832
535
|
}
|
|
833
536
|
},
|
|
@@ -835,22 +538,17 @@ var cursorConverter = (accessor) => ({
|
|
|
835
538
|
try {
|
|
836
539
|
return fromCursor(accessor, cursor);
|
|
837
540
|
} catch (err) {
|
|
838
|
-
|
|
839
|
-
F: __dxlog_file3,
|
|
840
|
-
L: 24,
|
|
841
|
-
S: void 0,
|
|
842
|
-
C: (f, a) => f(...a)
|
|
843
|
-
});
|
|
541
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 19, S: void 0 });
|
|
844
542
|
return 0;
|
|
845
543
|
}
|
|
846
544
|
}
|
|
847
545
|
});
|
|
848
546
|
|
|
849
547
|
// src/extensions/automerge/defs.ts
|
|
850
|
-
import { Annotation, StateEffect
|
|
548
|
+
import { Annotation, StateEffect } from "@codemirror/state";
|
|
851
549
|
var getPath = (state, field) => state.field(field).path;
|
|
852
550
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
853
|
-
var updateHeadsEffect =
|
|
551
|
+
var updateHeadsEffect = StateEffect.define({});
|
|
854
552
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
855
553
|
newHeads
|
|
856
554
|
});
|
|
@@ -861,7 +559,7 @@ var isReconcile = (tr) => {
|
|
|
861
559
|
|
|
862
560
|
// src/extensions/automerge/sync.ts
|
|
863
561
|
import { next as A2 } from "@automerge/automerge";
|
|
864
|
-
import { log as
|
|
562
|
+
import { log as log3 } from "@dxos/log";
|
|
865
563
|
|
|
866
564
|
// src/extensions/automerge/update-automerge.ts
|
|
867
565
|
import { next as A } from "@automerge/automerge";
|
|
@@ -1002,7 +700,7 @@ var charPath = (textPath, candidatePath) => {
|
|
|
1002
700
|
};
|
|
1003
701
|
|
|
1004
702
|
// src/extensions/automerge/sync.ts
|
|
1005
|
-
var
|
|
703
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/automerge/sync.ts";
|
|
1006
704
|
var Syncer = class {
|
|
1007
705
|
_handle;
|
|
1008
706
|
_state;
|
|
@@ -1025,12 +723,7 @@ var Syncer = class {
|
|
|
1025
723
|
this._pending = false;
|
|
1026
724
|
}
|
|
1027
725
|
onEditorChange(view) {
|
|
1028
|
-
|
|
1029
|
-
F: __dxlog_file4,
|
|
1030
|
-
L: 45,
|
|
1031
|
-
S: this,
|
|
1032
|
-
C: (f, a) => f(...a)
|
|
1033
|
-
});
|
|
726
|
+
log3("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 35, S: this });
|
|
1034
727
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
1035
728
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
1036
729
|
if (newHeads) {
|
|
@@ -1041,12 +734,7 @@ var Syncer = class {
|
|
|
1041
734
|
}
|
|
1042
735
|
}
|
|
1043
736
|
onAutomergeChange(view) {
|
|
1044
|
-
|
|
1045
|
-
F: __dxlog_file4,
|
|
1046
|
-
L: 60,
|
|
1047
|
-
S: this,
|
|
1048
|
-
C: (f, a) => f(...a)
|
|
1049
|
-
});
|
|
737
|
+
log3("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 47, S: this });
|
|
1050
738
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
1051
739
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
1052
740
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1099,7 +787,7 @@ var automerge = (accessor) => {
|
|
|
1099
787
|
// Track heads.
|
|
1100
788
|
syncState,
|
|
1101
789
|
// Reconcile external updates.
|
|
1102
|
-
|
|
790
|
+
ViewPlugin5.fromClass(class {
|
|
1103
791
|
_view;
|
|
1104
792
|
constructor(_view) {
|
|
1105
793
|
this._view = _view;
|
|
@@ -1108,14 +796,16 @@ var automerge = (accessor) => {
|
|
|
1108
796
|
const value = DocAccessor.getValue(accessor);
|
|
1109
797
|
const current = this._view.state.doc.toString();
|
|
1110
798
|
if (value !== current) {
|
|
1111
|
-
console.warn("ENABLING INITIAL SYNC -- THIS MAY BE A REGRESSION");
|
|
1112
799
|
this._view.dispatch({
|
|
1113
800
|
changes: {
|
|
1114
801
|
from: 0,
|
|
1115
802
|
to: this._view.state.doc.length,
|
|
1116
803
|
insert: value
|
|
1117
804
|
},
|
|
1118
|
-
annotations:
|
|
805
|
+
annotations: [
|
|
806
|
+
initialSync,
|
|
807
|
+
reconcileAnnotation.of(true)
|
|
808
|
+
]
|
|
1119
809
|
});
|
|
1120
810
|
}
|
|
1121
811
|
});
|
|
@@ -1128,7 +818,7 @@ var automerge = (accessor) => {
|
|
|
1128
818
|
};
|
|
1129
819
|
}),
|
|
1130
820
|
// Reconcile local updates.
|
|
1131
|
-
|
|
821
|
+
EditorView4.updateListener.of(({ view, changes, transactions }) => {
|
|
1132
822
|
if (!changes.empty) {
|
|
1133
823
|
const isInitialSync = transactions.some((tr) => tr.annotation(Transaction2.userEvent) === initialSync.value);
|
|
1134
824
|
if (!isInitialSync) {
|
|
@@ -1141,10 +831,10 @@ var automerge = (accessor) => {
|
|
|
1141
831
|
|
|
1142
832
|
// src/extensions/awareness/awareness.ts
|
|
1143
833
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
|
1144
|
-
import { Decoration as Decoration5, EditorView as
|
|
834
|
+
import { Decoration as Decoration5, EditorView as EditorView5, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1145
835
|
import { Event } from "@dxos/async";
|
|
1146
836
|
import { Context } from "@dxos/context";
|
|
1147
|
-
var
|
|
837
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/awareness/awareness.ts";
|
|
1148
838
|
var dummyProvider = {
|
|
1149
839
|
remoteStateChange: new Event(),
|
|
1150
840
|
open: () => {
|
|
@@ -1160,17 +850,14 @@ var RemoteSelectionChangedAnnotation = Annotation2.define();
|
|
|
1160
850
|
var awareness = (provider = dummyProvider) => {
|
|
1161
851
|
return [
|
|
1162
852
|
awarenessProvider.of(provider),
|
|
1163
|
-
|
|
853
|
+
ViewPlugin6.fromClass(RemoteSelectionsDecorator, {
|
|
1164
854
|
decorations: (value) => value.decorations
|
|
1165
855
|
}),
|
|
1166
856
|
styles
|
|
1167
857
|
];
|
|
1168
858
|
};
|
|
1169
859
|
var RemoteSelectionsDecorator = class {
|
|
1170
|
-
_ctx = new Context(void 0, {
|
|
1171
|
-
F: __dxlog_file5,
|
|
1172
|
-
L: 80
|
|
1173
|
-
});
|
|
860
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 33 });
|
|
1174
861
|
_cursorConverter;
|
|
1175
862
|
_provider;
|
|
1176
863
|
_lastAnchor;
|
|
@@ -1319,7 +1006,7 @@ var RemoteCaretWidget = class extends WidgetType3 {
|
|
|
1319
1006
|
return true;
|
|
1320
1007
|
}
|
|
1321
1008
|
};
|
|
1322
|
-
var styles =
|
|
1009
|
+
var styles = EditorView5.theme({
|
|
1323
1010
|
".cm-collab-selection": {},
|
|
1324
1011
|
".cm-collab-selectionLine": {
|
|
1325
1012
|
padding: 0,
|
|
@@ -1381,8 +1068,8 @@ var styles = EditorView7.theme({
|
|
|
1381
1068
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
1382
1069
|
import { Context as Context2 } from "@dxos/context";
|
|
1383
1070
|
import { invariant } from "@dxos/invariant";
|
|
1384
|
-
import { log as
|
|
1385
|
-
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";
|
|
1386
1073
|
var DEBOUNCE_INTERVAL = 100;
|
|
1387
1074
|
var SpaceAwarenessProvider = class {
|
|
1388
1075
|
_remoteStates = /* @__PURE__ */ new Map();
|
|
@@ -1401,10 +1088,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1401
1088
|
this._info = info;
|
|
1402
1089
|
}
|
|
1403
1090
|
open() {
|
|
1404
|
-
this._ctx = new Context2(void 0, {
|
|
1405
|
-
F: __dxlog_file6,
|
|
1406
|
-
L: 57
|
|
1407
|
-
});
|
|
1091
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 28 });
|
|
1408
1092
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1409
1093
|
if (this._localState) {
|
|
1410
1094
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1429,14 +1113,9 @@ var SpaceAwarenessProvider = class {
|
|
|
1429
1113
|
void this._messenger.postMessage(this._channel, {
|
|
1430
1114
|
kind: "query"
|
|
1431
1115
|
}).catch((err) => {
|
|
1432
|
-
|
|
1116
|
+
log4.debug("failed to query awareness", {
|
|
1433
1117
|
err
|
|
1434
|
-
}, {
|
|
1435
|
-
F: __dxlog_file6,
|
|
1436
|
-
L: 91,
|
|
1437
|
-
S: this,
|
|
1438
|
-
C: (f, a) => f(...a)
|
|
1439
|
-
});
|
|
1118
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 57, S: this });
|
|
1440
1119
|
});
|
|
1441
1120
|
}
|
|
1442
1121
|
close() {
|
|
@@ -1448,15 +1127,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1448
1127
|
return Array.from(this._remoteStates.values());
|
|
1449
1128
|
}
|
|
1450
1129
|
update(position) {
|
|
1451
|
-
invariant(this._postTask, void 0, {
|
|
1452
|
-
F: __dxlog_file6,
|
|
1453
|
-
L: 106,
|
|
1454
|
-
S: this,
|
|
1455
|
-
A: [
|
|
1456
|
-
"this._postTask",
|
|
1457
|
-
""
|
|
1458
|
-
]
|
|
1459
|
-
});
|
|
1130
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1460
1131
|
this._localState = {
|
|
1461
1132
|
peerId: this._peerId,
|
|
1462
1133
|
position,
|
|
@@ -1465,38 +1136,22 @@ var SpaceAwarenessProvider = class {
|
|
|
1465
1136
|
this._postTask.schedule();
|
|
1466
1137
|
}
|
|
1467
1138
|
_handleQueryMessage() {
|
|
1468
|
-
invariant(this._postTask, void 0, {
|
|
1469
|
-
F: __dxlog_file6,
|
|
1470
|
-
L: 117,
|
|
1471
|
-
S: this,
|
|
1472
|
-
A: [
|
|
1473
|
-
"this._postTask",
|
|
1474
|
-
""
|
|
1475
|
-
]
|
|
1476
|
-
});
|
|
1139
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1477
1140
|
this._postTask.schedule();
|
|
1478
1141
|
}
|
|
1479
1142
|
_handlePostMessage(message) {
|
|
1480
|
-
invariant(message.kind === "post", void 0, {
|
|
1481
|
-
F: __dxlog_file6,
|
|
1482
|
-
L: 122,
|
|
1483
|
-
S: this,
|
|
1484
|
-
A: [
|
|
1485
|
-
"message.kind === 'post'",
|
|
1486
|
-
""
|
|
1487
|
-
]
|
|
1488
|
-
});
|
|
1143
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1489
1144
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1490
1145
|
this.remoteStateChange.emit();
|
|
1491
1146
|
}
|
|
1492
1147
|
};
|
|
1493
1148
|
|
|
1494
1149
|
// src/extensions/blast.ts
|
|
1495
|
-
import { EditorView as
|
|
1150
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
|
1496
1151
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
1497
|
-
import { throttle
|
|
1152
|
+
import { throttle } from "@dxos/async";
|
|
1498
1153
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1499
|
-
var
|
|
1154
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/blast.ts";
|
|
1500
1155
|
var defaultOptions = {
|
|
1501
1156
|
effect: 2,
|
|
1502
1157
|
maxParticles: 200,
|
|
@@ -1541,7 +1196,7 @@ var blast = (options = defaultOptions) => {
|
|
|
1541
1196
|
};
|
|
1542
1197
|
return [
|
|
1543
1198
|
// Cursor moved.
|
|
1544
|
-
|
|
1199
|
+
EditorView6.updateListener.of((update2) => {
|
|
1545
1200
|
if (blaster?.node !== update2.view.scrollDOM) {
|
|
1546
1201
|
if (blaster) {
|
|
1547
1202
|
blaster.destroy();
|
|
@@ -1614,15 +1269,7 @@ var Blaster = class {
|
|
|
1614
1269
|
return this._node;
|
|
1615
1270
|
}
|
|
1616
1271
|
initialize() {
|
|
1617
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1618
|
-
F: __dxlog_file7,
|
|
1619
|
-
L: 142,
|
|
1620
|
-
S: this,
|
|
1621
|
-
A: [
|
|
1622
|
-
"!this._canvas && !this._ctx",
|
|
1623
|
-
""
|
|
1624
|
-
]
|
|
1625
|
-
});
|
|
1272
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1626
1273
|
this._canvas = document.createElement("canvas");
|
|
1627
1274
|
this._canvas.id = "code-blast-canvas";
|
|
1628
1275
|
this._canvas.style.position = "absolute";
|
|
@@ -1651,15 +1298,7 @@ var Blaster = class {
|
|
|
1651
1298
|
}
|
|
1652
1299
|
}
|
|
1653
1300
|
start() {
|
|
1654
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1655
|
-
F: __dxlog_file7,
|
|
1656
|
-
L: 181,
|
|
1657
|
-
S: this,
|
|
1658
|
-
A: [
|
|
1659
|
-
"this._canvas && this._ctx",
|
|
1660
|
-
""
|
|
1661
|
-
]
|
|
1662
|
-
});
|
|
1301
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1663
1302
|
this._running = true;
|
|
1664
1303
|
this.loop();
|
|
1665
1304
|
}
|
|
@@ -1686,11 +1325,11 @@ var Blaster = class {
|
|
|
1686
1325
|
this.drawParticles();
|
|
1687
1326
|
requestAnimationFrame(this.loop.bind(this));
|
|
1688
1327
|
}
|
|
1689
|
-
shake =
|
|
1328
|
+
shake = throttle(({ time }) => {
|
|
1690
1329
|
this._shakeTime = this._shakeTimeMax || time;
|
|
1691
1330
|
this._shakeTimeMax = time;
|
|
1692
1331
|
}, 100);
|
|
1693
|
-
spawn =
|
|
1332
|
+
spawn = throttle(({ element, point }) => {
|
|
1694
1333
|
const color = getRGBComponents(element, this._options.color);
|
|
1695
1334
|
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
1696
1335
|
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
@@ -1799,9 +1438,9 @@ var random = (min, max) => {
|
|
|
1799
1438
|
|
|
1800
1439
|
// src/extensions/blocks.ts
|
|
1801
1440
|
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1802
|
-
import { Decoration as Decoration6, EditorView as
|
|
1441
|
+
import { Decoration as Decoration6, EditorView as EditorView7, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
|
1803
1442
|
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1804
|
-
var paragraphBlockPlugin =
|
|
1443
|
+
var paragraphBlockPlugin = ViewPlugin7.fromClass(class {
|
|
1805
1444
|
decorations;
|
|
1806
1445
|
constructor(view) {
|
|
1807
1446
|
this.decorations = this.build(view);
|
|
@@ -1860,7 +1499,7 @@ var paragraphBlockPlugin = ViewPlugin9.fromClass(class {
|
|
|
1860
1499
|
});
|
|
1861
1500
|
var blocks = () => [
|
|
1862
1501
|
paragraphBlockPlugin,
|
|
1863
|
-
|
|
1502
|
+
EditorView7.baseTheme({
|
|
1864
1503
|
".cm-line.block-line": {
|
|
1865
1504
|
paddingLeft: "0.75rem",
|
|
1866
1505
|
paddingRight: "0.75rem",
|
|
@@ -1894,13 +1533,13 @@ var blocks = () => [
|
|
|
1894
1533
|
];
|
|
1895
1534
|
|
|
1896
1535
|
// src/extensions/bookmarks.ts
|
|
1897
|
-
import { Prec as Prec3, StateEffect as
|
|
1536
|
+
import { Prec as Prec3, StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1898
1537
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1899
|
-
import { log as
|
|
1900
|
-
var
|
|
1901
|
-
var addBookmark =
|
|
1902
|
-
var removeBookmark =
|
|
1903
|
-
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();
|
|
1904
1543
|
var bookmarks = () => {
|
|
1905
1544
|
return [
|
|
1906
1545
|
bookmarksField,
|
|
@@ -1909,12 +1548,7 @@ var bookmarks = () => {
|
|
|
1909
1548
|
key: "Mod-ArrowUp",
|
|
1910
1549
|
run: (view) => {
|
|
1911
1550
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1912
|
-
|
|
1913
|
-
F: __dxlog_file8,
|
|
1914
|
-
L: 29,
|
|
1915
|
-
S: void 0,
|
|
1916
|
-
C: (f, a) => f(...a)
|
|
1917
|
-
});
|
|
1551
|
+
log5("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 18, S: void 0 });
|
|
1918
1552
|
return true;
|
|
1919
1553
|
}
|
|
1920
1554
|
},
|
|
@@ -1922,12 +1556,7 @@ var bookmarks = () => {
|
|
|
1922
1556
|
key: "Mod-ArrowDown",
|
|
1923
1557
|
run: (view) => {
|
|
1924
1558
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1925
|
-
|
|
1926
|
-
F: __dxlog_file8,
|
|
1927
|
-
L: 37,
|
|
1928
|
-
S: void 0,
|
|
1929
|
-
C: (f, a) => f(...a)
|
|
1930
|
-
});
|
|
1559
|
+
log5("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 26, S: void 0 });
|
|
1931
1560
|
return true;
|
|
1932
1561
|
}
|
|
1933
1562
|
}
|
|
@@ -1964,27 +1593,27 @@ var bookmarksField = StateField2.define({
|
|
|
1964
1593
|
|
|
1965
1594
|
// src/extensions/comments.ts
|
|
1966
1595
|
import { invertedEffects } from "@codemirror/commands";
|
|
1967
|
-
import { StateEffect as
|
|
1968
|
-
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";
|
|
1969
1598
|
import sortBy from "lodash.sortby";
|
|
1970
1599
|
import { debounce as debounce2 } from "@dxos/async";
|
|
1971
|
-
import { log as
|
|
1600
|
+
import { log as log6 } from "@dxos/log";
|
|
1972
1601
|
import { isNonNullable } from "@dxos/util";
|
|
1973
1602
|
|
|
1974
1603
|
// src/extensions/selection.ts
|
|
1975
1604
|
import { Transaction as Transaction3 } from "@codemirror/state";
|
|
1976
|
-
import { EditorView as
|
|
1605
|
+
import { EditorView as EditorView8, keymap as keymap5 } from "@codemirror/view";
|
|
1977
1606
|
import { debounce } from "@dxos/async";
|
|
1978
1607
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1979
1608
|
import { isTruthy } from "@dxos/util";
|
|
1980
|
-
var
|
|
1609
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1981
1610
|
var documentId = singleValueFacet();
|
|
1982
1611
|
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1983
1612
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1984
1613
|
return {
|
|
1985
1614
|
selection,
|
|
1986
1615
|
scrollIntoView: !scrollTo,
|
|
1987
|
-
effects: scrollTo ?
|
|
1616
|
+
effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
|
|
1988
1617
|
yMargin: 96
|
|
1989
1618
|
}) : void 0,
|
|
1990
1619
|
annotations: Transaction3.userEvent.of(stateRestoreAnnotation)
|
|
@@ -1992,28 +1621,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1992
1621
|
};
|
|
1993
1622
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1994
1623
|
getState: (id) => {
|
|
1995
|
-
invariant3(id, void 0, {
|
|
1996
|
-
F: __dxlog_file9,
|
|
1997
|
-
L: 47,
|
|
1998
|
-
S: void 0,
|
|
1999
|
-
A: [
|
|
2000
|
-
"id",
|
|
2001
|
-
""
|
|
2002
|
-
]
|
|
2003
|
-
});
|
|
1624
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0, A: ["id", ""] });
|
|
2004
1625
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
2005
1626
|
return state ? JSON.parse(state) : void 0;
|
|
2006
1627
|
},
|
|
2007
1628
|
setState: (id, state) => {
|
|
2008
|
-
invariant3(id, void 0, {
|
|
2009
|
-
F: __dxlog_file9,
|
|
2010
|
-
L: 53,
|
|
2011
|
-
S: void 0,
|
|
2012
|
-
A: [
|
|
2013
|
-
"id",
|
|
2014
|
-
""
|
|
2015
|
-
]
|
|
2016
|
-
});
|
|
1629
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 31, S: void 0, A: ["id", ""] });
|
|
2017
1630
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
2018
1631
|
}
|
|
2019
1632
|
});
|
|
@@ -2026,7 +1639,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2026
1639
|
// setStateDebounced(id, {});
|
|
2027
1640
|
// },
|
|
2028
1641
|
// }),
|
|
2029
|
-
|
|
1642
|
+
EditorView8.updateListener.of(({ view, transactions }) => {
|
|
2030
1643
|
const id = view.state.facet(documentId);
|
|
2031
1644
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
|
2032
1645
|
return;
|
|
@@ -2065,10 +1678,10 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2065
1678
|
};
|
|
2066
1679
|
|
|
2067
1680
|
// src/extensions/comments.ts
|
|
2068
|
-
var
|
|
2069
|
-
var setComments =
|
|
2070
|
-
var setSelection =
|
|
2071
|
-
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();
|
|
2072
1685
|
var commentsState = StateField3.define({
|
|
2073
1686
|
create: (state) => ({
|
|
2074
1687
|
id: state.facet(documentId),
|
|
@@ -2107,7 +1720,7 @@ var commentsState = StateField3.define({
|
|
|
2107
1720
|
return value;
|
|
2108
1721
|
}
|
|
2109
1722
|
});
|
|
2110
|
-
var styles2 =
|
|
1723
|
+
var styles2 = EditorView9.theme({
|
|
2111
1724
|
".cm-comment, .cm-comment-current": {
|
|
2112
1725
|
padding: "3px 0",
|
|
2113
1726
|
color: "var(--color-cm-comment-text)",
|
|
@@ -2128,19 +1741,14 @@ var createCommentMark = (id, isCurrent) => Decoration7.mark({
|
|
|
2128
1741
|
"data-comment-id": id
|
|
2129
1742
|
}
|
|
2130
1743
|
});
|
|
2131
|
-
var commentsDecorations =
|
|
1744
|
+
var commentsDecorations = EditorView9.decorations.compute([
|
|
2132
1745
|
commentsState
|
|
2133
1746
|
], (state) => {
|
|
2134
1747
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
2135
1748
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2136
1749
|
const range = comment.range;
|
|
2137
1750
|
if (!range) {
|
|
2138
|
-
|
|
2139
|
-
F: __dxlog_file10,
|
|
2140
|
-
L: 139,
|
|
2141
|
-
S: void 0,
|
|
2142
|
-
C: (f, a) => f(...a)
|
|
2143
|
-
});
|
|
1751
|
+
log6.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 93, S: void 0 });
|
|
2144
1752
|
return void 0;
|
|
2145
1753
|
} else if (range.from === range.to) {
|
|
2146
1754
|
return void 0;
|
|
@@ -2150,8 +1758,8 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2150
1758
|
}).filter(isNonNullable);
|
|
2151
1759
|
return Decoration7.set(decorations2);
|
|
2152
1760
|
});
|
|
2153
|
-
var commentClickedEffect =
|
|
2154
|
-
var handleCommentClick =
|
|
1761
|
+
var commentClickedEffect = StateEffect3.define();
|
|
1762
|
+
var handleCommentClick = EditorView9.domEventHandlers({
|
|
2155
1763
|
click: (event, view) => {
|
|
2156
1764
|
let target = event.target;
|
|
2157
1765
|
const editorRoot = view.dom;
|
|
@@ -2190,7 +1798,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2190
1798
|
}
|
|
2191
1799
|
};
|
|
2192
1800
|
return [
|
|
2193
|
-
|
|
1801
|
+
EditorView9.domEventHandlers({
|
|
2194
1802
|
cut: handleTrack,
|
|
2195
1803
|
copy: handleTrack
|
|
2196
1804
|
}),
|
|
@@ -2212,7 +1820,7 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2212
1820
|
return effects;
|
|
2213
1821
|
}),
|
|
2214
1822
|
// Handle paste or the undo of comment deletion.
|
|
2215
|
-
|
|
1823
|
+
EditorView9.updateListener.of((update2) => {
|
|
2216
1824
|
const restore = [];
|
|
2217
1825
|
for (let i = 0; i < update2.transactions.length; i++) {
|
|
2218
1826
|
const tr = update2.transactions[i];
|
|
@@ -2268,7 +1876,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2268
1876
|
from: changes.mapPos(comment.from, 1),
|
|
2269
1877
|
to: changes.mapPos(comment.to, 1)
|
|
2270
1878
|
});
|
|
2271
|
-
var restoreCommentEffect =
|
|
1879
|
+
var restoreCommentEffect = StateEffect3.define({
|
|
2272
1880
|
map: mapTrackedComment
|
|
2273
1881
|
});
|
|
2274
1882
|
var createComment = (view) => {
|
|
@@ -2354,7 +1962,7 @@ var comments = (options = {}) => {
|
|
|
2354
1962
|
//
|
|
2355
1963
|
// Track deleted ranges and update ranges for decorations.
|
|
2356
1964
|
//
|
|
2357
|
-
|
|
1965
|
+
EditorView9.updateListener.of(({ view, state, changes }) => {
|
|
2358
1966
|
let mod = false;
|
|
2359
1967
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
2360
1968
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -2386,7 +1994,7 @@ var comments = (options = {}) => {
|
|
|
2386
1994
|
//
|
|
2387
1995
|
// Track selection/proximity.
|
|
2388
1996
|
//
|
|
2389
|
-
|
|
1997
|
+
EditorView9.updateListener.of(({ view, state }) => {
|
|
2390
1998
|
let min = Infinity;
|
|
2391
1999
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
2392
2000
|
const { head } = state.selection.main;
|
|
@@ -2440,7 +2048,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
|
2440
2048
|
anchor: range.from
|
|
2441
2049
|
} : void 0,
|
|
2442
2050
|
effects: [
|
|
2443
|
-
needsScroll ?
|
|
2051
|
+
needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
|
|
2444
2052
|
y: "center"
|
|
2445
2053
|
} : void 0) : [],
|
|
2446
2054
|
needsSelectionUpdate ? setSelection.of({
|
|
@@ -2471,7 +2079,7 @@ var ExternalCommentSync = class {
|
|
|
2471
2079
|
this.unsubscribe();
|
|
2472
2080
|
};
|
|
2473
2081
|
};
|
|
2474
|
-
var createExternalCommentSync = (id, subscribe, getComments) =>
|
|
2082
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin8.fromClass(class {
|
|
2475
2083
|
constructor(view) {
|
|
2476
2084
|
return new ExternalCommentSync(view, id, subscribe, getComments);
|
|
2477
2085
|
}
|
|
@@ -2491,12 +2099,12 @@ var debugNodeLogger = (log12 = console.log) => {
|
|
|
2491
2099
|
};
|
|
2492
2100
|
|
|
2493
2101
|
// src/extensions/dnd.ts
|
|
2494
|
-
import { EditorView as
|
|
2102
|
+
import { EditorView as EditorView10, dropCursor } from "@codemirror/view";
|
|
2495
2103
|
var dropFile = (options = {}) => {
|
|
2496
2104
|
return [
|
|
2497
2105
|
styles3,
|
|
2498
2106
|
dropCursor(),
|
|
2499
|
-
|
|
2107
|
+
EditorView10.domEventHandlers({
|
|
2500
2108
|
drop: (event, view) => {
|
|
2501
2109
|
event.preventDefault();
|
|
2502
2110
|
const files = event.dataTransfer?.files;
|
|
@@ -2515,7 +2123,7 @@ var dropFile = (options = {}) => {
|
|
|
2515
2123
|
})
|
|
2516
2124
|
];
|
|
2517
2125
|
};
|
|
2518
|
-
var styles3 =
|
|
2126
|
+
var styles3 = EditorView10.theme({
|
|
2519
2127
|
".cm-dropCursor": {
|
|
2520
2128
|
borderLeft: "2px solid var(--color-accent-text)",
|
|
2521
2129
|
color: "var(--color-accent-text)",
|
|
@@ -2537,10 +2145,10 @@ import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode"
|
|
|
2537
2145
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2538
2146
|
import { generateName } from "@dxos/display-name";
|
|
2539
2147
|
import { log as log8 } from "@dxos/log";
|
|
2540
|
-
import { hexToHue, isTruthy as
|
|
2148
|
+
import { hexToHue, isTruthy as isTruthy3 } from "@dxos/util";
|
|
2541
2149
|
|
|
2542
2150
|
// src/styles/theme.ts
|
|
2543
|
-
import { EditorView as
|
|
2151
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
2544
2152
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2545
2153
|
var headings = {
|
|
2546
2154
|
1: {
|
|
@@ -2588,7 +2196,7 @@ var markdownTheme = {
|
|
|
2588
2196
|
fontWeight: "100 !important"
|
|
2589
2197
|
})
|
|
2590
2198
|
};
|
|
2591
|
-
var baseTheme =
|
|
2199
|
+
var baseTheme = EditorView11.baseTheme({
|
|
2592
2200
|
/**
|
|
2593
2201
|
* Outer frame.
|
|
2594
2202
|
*/
|
|
@@ -2600,12 +2208,21 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2600
2208
|
* Scroller
|
|
2601
2209
|
*/
|
|
2602
2210
|
".cm-scroller": {
|
|
2603
|
-
|
|
2211
|
+
// Browser scroll-anchoring: see comment in `scrolling/crawler.ts`. `auto` lets the browser pin a
|
|
2212
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2213
|
+
// open/close) don't jump the user's view.
|
|
2214
|
+
overflowAnchor: "auto"
|
|
2604
2215
|
},
|
|
2605
2216
|
".cm-scroller::-webkit-scrollbar": {
|
|
2606
|
-
width: "8px"
|
|
2217
|
+
width: "var(--scrollbar-size,8px)",
|
|
2218
|
+
height: "var(--scrollbar-size,8px)"
|
|
2219
|
+
},
|
|
2220
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2221
|
+
background: "transparent"
|
|
2222
|
+
},
|
|
2223
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2224
|
+
background: "transparent"
|
|
2607
2225
|
},
|
|
2608
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2609
2226
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2610
2227
|
background: "transparent",
|
|
2611
2228
|
transition: "background 0.15s"
|
|
@@ -2642,7 +2259,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2642
2259
|
* Height is set to match the corresponding line (which may have wrapped).
|
|
2643
2260
|
*/
|
|
2644
2261
|
".cm-gutterElement": {
|
|
2645
|
-
lineHeight:
|
|
2262
|
+
lineHeight: "24px",
|
|
2646
2263
|
fontSize: "12px"
|
|
2647
2264
|
},
|
|
2648
2265
|
/**
|
|
@@ -2702,7 +2319,8 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2702
2319
|
textDecorationThickness: "1px",
|
|
2703
2320
|
textDecorationColor: "var(--color-separator)",
|
|
2704
2321
|
textUnderlineOffset: "2px",
|
|
2705
|
-
borderRadius: ".125rem"
|
|
2322
|
+
borderRadius: ".125rem",
|
|
2323
|
+
cursor: "pointer"
|
|
2706
2324
|
},
|
|
2707
2325
|
".cm-link > span": {
|
|
2708
2326
|
color: "var(--color-accent-text)"
|
|
@@ -2740,12 +2358,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2740
2358
|
padding: "4px"
|
|
2741
2359
|
},
|
|
2742
2360
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2743
|
-
background: "var(--color-
|
|
2744
|
-
color: "var(--color-base-
|
|
2361
|
+
background: "var(--color-current-surface)",
|
|
2362
|
+
color: "var(--color-base-foreground)"
|
|
2745
2363
|
},
|
|
2746
2364
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2747
2365
|
paddingLeft: "4px !important",
|
|
2748
|
-
color: "var(--color-base-
|
|
2366
|
+
color: "var(--color-base-foreground)"
|
|
2749
2367
|
},
|
|
2750
2368
|
/**
|
|
2751
2369
|
* Completion info.
|
|
@@ -2764,7 +2382,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2764
2382
|
padding: "0 4px"
|
|
2765
2383
|
},
|
|
2766
2384
|
".cm-completionMatchedText": {
|
|
2767
|
-
color: "var(--color-base-
|
|
2385
|
+
color: "var(--color-base-foreground)",
|
|
2768
2386
|
textDecoration: "none !important"
|
|
2769
2387
|
},
|
|
2770
2388
|
/**
|
|
@@ -2799,7 +2417,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2799
2417
|
backgroundColor: "var(--color-input-surface)"
|
|
2800
2418
|
},
|
|
2801
2419
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2802
|
-
outline: "1px solid var(--color-
|
|
2420
|
+
outline: "1px solid var(--color-focus-ring-subtle)"
|
|
2803
2421
|
},
|
|
2804
2422
|
".cm-panel label": {
|
|
2805
2423
|
display: "inline-flex",
|
|
@@ -2812,7 +2430,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2812
2430
|
height: "8px",
|
|
2813
2431
|
marginRight: "6px !important",
|
|
2814
2432
|
padding: "2px !important",
|
|
2815
|
-
color: "var(--color-
|
|
2433
|
+
color: "var(--color-focus-ring-subtle)"
|
|
2816
2434
|
},
|
|
2817
2435
|
".cm-panel button": {
|
|
2818
2436
|
"&:hover": {
|
|
@@ -2828,14 +2446,14 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2828
2446
|
borderTop: "1px solid var(--color-separator)"
|
|
2829
2447
|
}
|
|
2830
2448
|
});
|
|
2831
|
-
var editorGutter =
|
|
2449
|
+
var editorGutter = EditorView11.theme({
|
|
2832
2450
|
".cm-gutters": {
|
|
2833
2451
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
2834
2452
|
background: "var(--color-base-surface) !important",
|
|
2835
2453
|
paddingRight: "1rem"
|
|
2836
2454
|
}
|
|
2837
2455
|
});
|
|
2838
|
-
var createFontTheme = ({ monospace } = {}) =>
|
|
2456
|
+
var createFontTheme = ({ monospace } = {}) => EditorView11.theme({
|
|
2839
2457
|
// Main content.
|
|
2840
2458
|
".cm-scroller": {
|
|
2841
2459
|
fontFamily: monospace ? fontMono : fontBody
|
|
@@ -2848,9 +2466,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2848
2466
|
});
|
|
2849
2467
|
|
|
2850
2468
|
// src/extensions/focus.ts
|
|
2851
|
-
import { StateEffect as
|
|
2852
|
-
import { EditorView as
|
|
2853
|
-
var focusEffect =
|
|
2469
|
+
import { StateEffect as StateEffect4, StateField as StateField5 } from "@codemirror/state";
|
|
2470
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
|
2471
|
+
var focusEffect = StateEffect4.define();
|
|
2854
2472
|
var focusField = StateField5.define({
|
|
2855
2473
|
create: () => false,
|
|
2856
2474
|
update: (value, tr) => {
|
|
@@ -2864,7 +2482,7 @@ var focusField = StateField5.define({
|
|
|
2864
2482
|
});
|
|
2865
2483
|
var focus = [
|
|
2866
2484
|
focusField,
|
|
2867
|
-
|
|
2485
|
+
EditorView12.domEventHandlers({
|
|
2868
2486
|
focus: (_event, view) => {
|
|
2869
2487
|
requestAnimationFrame(() => view.dispatch({
|
|
2870
2488
|
effects: focusEffect.of(true)
|
|
@@ -2875,22 +2493,365 @@ var focus = [
|
|
|
2875
2493
|
effects: focusEffect.of(false)
|
|
2876
2494
|
}));
|
|
2877
2495
|
}
|
|
2878
|
-
})
|
|
2879
|
-
];
|
|
2496
|
+
})
|
|
2497
|
+
];
|
|
2498
|
+
|
|
2499
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2500
|
+
import { StateEffect as StateEffect6 } from "@codemirror/state";
|
|
2501
|
+
import { EditorView as EditorView14, ViewPlugin as ViewPlugin10 } from "@codemirror/view";
|
|
2502
|
+
import { addEventListener, combine, throttle as throttle2 } from "@dxos/async";
|
|
2503
|
+
import { Domino } from "@dxos/ui";
|
|
2504
|
+
import { getSize } from "@dxos/ui-theme";
|
|
2505
|
+
|
|
2506
|
+
// src/extensions/scrolling/crawler.ts
|
|
2507
|
+
import { StateEffect as StateEffect5 } from "@codemirror/state";
|
|
2508
|
+
import { EditorView as EditorView13, ViewPlugin as ViewPlugin9 } from "@codemirror/view";
|
|
2509
|
+
import { log as log7 } from "@dxos/log";
|
|
2510
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/scrolling/crawler.ts";
|
|
2511
|
+
var crawlerLineEffect = StateEffect5.define();
|
|
2512
|
+
var crawlerActiveEffect = StateEffect5.define();
|
|
2513
|
+
var scrollToLine = (view, options) => {
|
|
2514
|
+
view.dispatch({
|
|
2515
|
+
effects: crawlerLineEffect.of(options)
|
|
2516
|
+
});
|
|
2517
|
+
};
|
|
2518
|
+
var crawler = ({ overScroll = 0 } = {}) => {
|
|
2519
|
+
const crawlerPlugin = ViewPlugin9.fromClass(class CrawlerPlugin {
|
|
2520
|
+
view;
|
|
2521
|
+
crawler;
|
|
2522
|
+
constructor(view) {
|
|
2523
|
+
this.view = view;
|
|
2524
|
+
this.crawler = createCrawler(this.view);
|
|
2525
|
+
}
|
|
2526
|
+
// No-op.
|
|
2527
|
+
destroy() {
|
|
2528
|
+
this.crawler.cancel();
|
|
2529
|
+
}
|
|
2530
|
+
cancel() {
|
|
2531
|
+
this.crawler.cancel();
|
|
2532
|
+
}
|
|
2533
|
+
crawl(start = false) {
|
|
2534
|
+
if (start) {
|
|
2535
|
+
this.crawler.scroll();
|
|
2536
|
+
} else {
|
|
2537
|
+
this.crawler.cancel();
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
scroll({ line, offset = 0, position, behavior = "instant" }) {
|
|
2541
|
+
const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
|
|
2542
|
+
const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
|
|
2543
|
+
const doc = this.view.state.doc;
|
|
2544
|
+
let targetScrollTop = scrollHeight - clientHeight + offset;
|
|
2545
|
+
if (line >= 0 && line <= doc.lines - 1) {
|
|
2546
|
+
const lineStart = doc.line(line + 1).from;
|
|
2547
|
+
const coords = this.view.coordsAtPos(lineStart);
|
|
2548
|
+
if (coords) {
|
|
2549
|
+
const currentScrollTop = scrollTop;
|
|
2550
|
+
const maxScrollTop = scrollHeight - clientHeight;
|
|
2551
|
+
if (position === "end") {
|
|
2552
|
+
targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
|
|
2553
|
+
} else {
|
|
2554
|
+
targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
|
|
2555
|
+
}
|
|
2556
|
+
targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
requestAnimationFrame(() => {
|
|
2560
|
+
this.view.scrollDOM.scrollTo({
|
|
2561
|
+
top: targetScrollTop
|
|
2562
|
+
});
|
|
2563
|
+
});
|
|
2564
|
+
}
|
|
2565
|
+
});
|
|
2566
|
+
return [
|
|
2567
|
+
crawlerPlugin,
|
|
2568
|
+
// Listen for effect.
|
|
2569
|
+
EditorView13.updateListener.of((update2) => {
|
|
2570
|
+
update2.transactions.forEach((transaction) => {
|
|
2571
|
+
try {
|
|
2572
|
+
const plugin = update2.view.plugin(crawlerPlugin);
|
|
2573
|
+
if (plugin) {
|
|
2574
|
+
for (const effect of transaction.effects) {
|
|
2575
|
+
if (effect.is(crawlerActiveEffect)) {
|
|
2576
|
+
plugin.crawl(effect.value);
|
|
2577
|
+
} else if (effect.is(crawlerLineEffect)) {
|
|
2578
|
+
plugin.scroll(effect.value);
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
} catch (err) {
|
|
2583
|
+
log7.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 98, S: void 0 });
|
|
2584
|
+
}
|
|
2585
|
+
});
|
|
2586
|
+
}),
|
|
2587
|
+
// Styles.
|
|
2588
|
+
EditorView13.theme({
|
|
2589
|
+
".cm-scroller": {
|
|
2590
|
+
overflowY: "scroll",
|
|
2591
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
2592
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
2593
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
2594
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
2595
|
+
overflowAnchor: "auto"
|
|
2596
|
+
},
|
|
2597
|
+
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
2598
|
+
display: "none"
|
|
2599
|
+
},
|
|
2600
|
+
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2601
|
+
background: "transparent",
|
|
2602
|
+
transition: "background 0.15s"
|
|
2603
|
+
},
|
|
2604
|
+
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
2605
|
+
background: "var(--color-scrollbar-thumb)"
|
|
2606
|
+
},
|
|
2607
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
2608
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
2609
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
2610
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
2611
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
2612
|
+
".cm-content::after": {
|
|
2613
|
+
content: '""',
|
|
2614
|
+
display: "block",
|
|
2615
|
+
height: `${overScroll}px`
|
|
2616
|
+
},
|
|
2617
|
+
".cm-scroll-button": {
|
|
2618
|
+
position: "absolute",
|
|
2619
|
+
bottom: "0.5rem",
|
|
2620
|
+
right: "1rem"
|
|
2621
|
+
}
|
|
2622
|
+
})
|
|
2623
|
+
];
|
|
2624
|
+
};
|
|
2625
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
2626
|
+
const el = view.scrollDOM;
|
|
2627
|
+
let currentTop = 0;
|
|
2628
|
+
let velocity = 0;
|
|
2629
|
+
let rafId = null;
|
|
2630
|
+
let lastTime = 0;
|
|
2631
|
+
function frame(now) {
|
|
2632
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
2633
|
+
lastTime = now;
|
|
2634
|
+
const targetTop = el.scrollHeight - el.clientHeight;
|
|
2635
|
+
const delta = targetTop - currentTop;
|
|
2636
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
2637
|
+
el.scrollTop = targetTop;
|
|
2638
|
+
currentTop = targetTop;
|
|
2639
|
+
velocity = 0;
|
|
2640
|
+
rafId = null;
|
|
2641
|
+
lastTime = 0;
|
|
2642
|
+
return;
|
|
2643
|
+
}
|
|
2644
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
2645
|
+
velocity += accel * dt;
|
|
2646
|
+
currentTop += velocity * dt;
|
|
2647
|
+
el.scrollTop = currentTop;
|
|
2648
|
+
rafId = requestAnimationFrame(frame);
|
|
2649
|
+
}
|
|
2650
|
+
return {
|
|
2651
|
+
scroll: () => {
|
|
2652
|
+
if (rafId === null) {
|
|
2653
|
+
currentTop = el.scrollTop;
|
|
2654
|
+
lastTime = 0;
|
|
2655
|
+
rafId = requestAnimationFrame(frame);
|
|
2656
|
+
}
|
|
2657
|
+
},
|
|
2658
|
+
cancel: () => {
|
|
2659
|
+
if (rafId !== null) {
|
|
2660
|
+
cancelAnimationFrame(rafId);
|
|
2661
|
+
velocity = 0;
|
|
2662
|
+
lastTime = 0;
|
|
2663
|
+
rafId = null;
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
};
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
// src/extensions/scrolling/auto-scroll.ts
|
|
2670
|
+
var autoScrollEffect = StateEffect6.define();
|
|
2671
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
2672
|
+
let buttonContainer;
|
|
2673
|
+
let isPinned = true;
|
|
2674
|
+
let jumpPending = false;
|
|
2675
|
+
let enabled = true;
|
|
2676
|
+
let firstUpdate = true;
|
|
2677
|
+
const setPinned = (pinned) => {
|
|
2678
|
+
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
2679
|
+
isPinned = pinned;
|
|
2680
|
+
};
|
|
2681
|
+
return [
|
|
2682
|
+
// Update listener for scrolling when content changes.
|
|
2683
|
+
EditorView14.updateListener.of((update2) => {
|
|
2684
|
+
const { view, heightChanged, state, startState } = update2;
|
|
2685
|
+
for (const tr of update2.transactions) {
|
|
2686
|
+
for (const effect of tr.effects) {
|
|
2687
|
+
if (effect.is(autoScrollEffect)) {
|
|
2688
|
+
enabled = effect.value;
|
|
2689
|
+
if (enabled) {
|
|
2690
|
+
setPinned(true);
|
|
2691
|
+
view.dispatch({
|
|
2692
|
+
effects: crawlerActiveEffect.of(true)
|
|
2693
|
+
});
|
|
2694
|
+
} else {
|
|
2695
|
+
view.dispatch({
|
|
2696
|
+
effects: crawlerActiveEffect.of(false)
|
|
2697
|
+
});
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
if (!enabled) {
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
2706
|
+
firstUpdate = false;
|
|
2707
|
+
jumpPending = true;
|
|
2708
|
+
requestAnimationFrame(() => {
|
|
2709
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
2710
|
+
jumpPending = false;
|
|
2711
|
+
});
|
|
2712
|
+
return;
|
|
2713
|
+
}
|
|
2714
|
+
firstUpdate = false;
|
|
2715
|
+
if (jumpPending) {
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
if (heightChanged) {
|
|
2719
|
+
if (isPinned) {
|
|
2720
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2721
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2722
|
+
if (delta > 0) {
|
|
2723
|
+
setPinned(true);
|
|
2724
|
+
view.dispatch({
|
|
2725
|
+
effects: crawlerActiveEffect.of(true)
|
|
2726
|
+
});
|
|
2727
|
+
} else if (delta < -1) {
|
|
2728
|
+
setPinned(false);
|
|
2729
|
+
}
|
|
2730
|
+
} else {
|
|
2731
|
+
if (state.doc.length === 0) {
|
|
2732
|
+
setPinned(true);
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
}),
|
|
2737
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
2738
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
2739
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
2740
|
+
scrollOnResize ? ViewPlugin10.fromClass(class {
|
|
2741
|
+
observer;
|
|
2742
|
+
firstObservation = true;
|
|
2743
|
+
destroyed = false;
|
|
2744
|
+
constructor(view) {
|
|
2745
|
+
const onResize = throttle2(() => {
|
|
2746
|
+
if (this.destroyed || !enabled) {
|
|
2747
|
+
return;
|
|
2748
|
+
}
|
|
2749
|
+
setPinned(true);
|
|
2750
|
+
requestAnimationFrame(() => {
|
|
2751
|
+
if (this.destroyed) {
|
|
2752
|
+
return;
|
|
2753
|
+
}
|
|
2754
|
+
view.scrollDOM.scrollTo({
|
|
2755
|
+
top: view.scrollDOM.scrollHeight,
|
|
2756
|
+
behavior: "instant"
|
|
2757
|
+
});
|
|
2758
|
+
view.dispatch({
|
|
2759
|
+
effects: crawlerActiveEffect.of(false)
|
|
2760
|
+
});
|
|
2761
|
+
});
|
|
2762
|
+
}, 50);
|
|
2763
|
+
this.observer = new ResizeObserver(() => {
|
|
2764
|
+
if (this.firstObservation) {
|
|
2765
|
+
this.firstObservation = false;
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
onResize();
|
|
2769
|
+
});
|
|
2770
|
+
this.observer.observe(view.scrollDOM);
|
|
2771
|
+
}
|
|
2772
|
+
destroy() {
|
|
2773
|
+
this.destroyed = true;
|
|
2774
|
+
this.observer.disconnect();
|
|
2775
|
+
}
|
|
2776
|
+
}) : [],
|
|
2777
|
+
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
2778
|
+
ViewPlugin10.fromClass(class {
|
|
2779
|
+
cleanup;
|
|
2780
|
+
constructor(view) {
|
|
2781
|
+
const onUserScroll = throttle2(() => {
|
|
2782
|
+
requestAnimationFrame(() => {
|
|
2783
|
+
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
2784
|
+
const delta = scrollHeight - scrollTop - clientHeight;
|
|
2785
|
+
const pinned = Math.abs(delta) <= 1;
|
|
2786
|
+
setPinned(pinned);
|
|
2787
|
+
if (!pinned) {
|
|
2788
|
+
view.dispatch({
|
|
2789
|
+
effects: crawlerActiveEffect.of(false)
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2792
|
+
});
|
|
2793
|
+
}, 500);
|
|
2794
|
+
this.cleanup = createUserScrollDetector(view.scrollDOM, () => {
|
|
2795
|
+
if (isPinned) {
|
|
2796
|
+
setPinned(false);
|
|
2797
|
+
view.dispatch({
|
|
2798
|
+
effects: crawlerActiveEffect.of(false)
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
onUserScroll();
|
|
2802
|
+
});
|
|
2803
|
+
}
|
|
2804
|
+
destroy() {
|
|
2805
|
+
this.cleanup();
|
|
2806
|
+
}
|
|
2807
|
+
}),
|
|
2808
|
+
// Scroll button.
|
|
2809
|
+
ViewPlugin10.fromClass(class {
|
|
2810
|
+
constructor(view) {
|
|
2811
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
2812
|
+
icon: "ph--arrow-down--regular"
|
|
2813
|
+
});
|
|
2814
|
+
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
2815
|
+
"data-density": "fine"
|
|
2816
|
+
}).append(icon).on("click", () => {
|
|
2817
|
+
setPinned(true);
|
|
2818
|
+
view.dispatch({
|
|
2819
|
+
effects: crawlerLineEffect.of({
|
|
2820
|
+
line: -1,
|
|
2821
|
+
position: "end",
|
|
2822
|
+
behavior: "smooth"
|
|
2823
|
+
})
|
|
2824
|
+
});
|
|
2825
|
+
});
|
|
2826
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
2827
|
+
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
2828
|
+
}
|
|
2829
|
+
})
|
|
2830
|
+
];
|
|
2831
|
+
};
|
|
2832
|
+
function createUserScrollDetector(element, onUserScroll) {
|
|
2833
|
+
return combine(addEventListener(element, "wheel", () => onUserScroll(), {
|
|
2834
|
+
passive: true
|
|
2835
|
+
}), addEventListener(element, "pointerdown", (event) => {
|
|
2836
|
+
if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {
|
|
2837
|
+
onUserScroll();
|
|
2838
|
+
}
|
|
2839
|
+
}));
|
|
2840
|
+
}
|
|
2880
2841
|
|
|
2881
|
-
// src/extensions/scroll-past-end.ts
|
|
2842
|
+
// src/extensions/scrolling/scroll-past-end.ts
|
|
2882
2843
|
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2883
2844
|
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
style:
|
|
2845
|
+
_height = 1e3;
|
|
2846
|
+
_attrs = {
|
|
2847
|
+
style: `padding-bottom: ${this._height}px`
|
|
2887
2848
|
};
|
|
2888
2849
|
update({ view }) {
|
|
2889
2850
|
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2890
2851
|
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2891
|
-
if (height >= 0 && height !== this.
|
|
2892
|
-
this.
|
|
2893
|
-
this.
|
|
2852
|
+
if (height >= 0 && height !== this._height) {
|
|
2853
|
+
this._height = height;
|
|
2854
|
+
this._attrs = {
|
|
2894
2855
|
style: `padding-bottom: ${height}px`
|
|
2895
2856
|
};
|
|
2896
2857
|
}
|
|
@@ -2898,9 +2859,22 @@ var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
|
2898
2859
|
});
|
|
2899
2860
|
var scrollPastEnd = () => [
|
|
2900
2861
|
scrollPastEndPlugin,
|
|
2901
|
-
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.
|
|
2862
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?._attrs ?? null)
|
|
2902
2863
|
];
|
|
2903
2864
|
|
|
2865
|
+
// src/extensions/scrolling/scroller.ts
|
|
2866
|
+
import { isTruthy as isTruthy2 } from "@dxos/util";
|
|
2867
|
+
var scroller = ({ overScroll, scrollOnResize, autoScroll: autoScroll2 = true } = {}) => {
|
|
2868
|
+
return [
|
|
2869
|
+
crawler({
|
|
2870
|
+
overScroll
|
|
2871
|
+
}),
|
|
2872
|
+
autoScroll2 && autoScroll({
|
|
2873
|
+
scrollOnResize
|
|
2874
|
+
})
|
|
2875
|
+
].filter(isTruthy2);
|
|
2876
|
+
};
|
|
2877
|
+
|
|
2904
2878
|
// src/extensions/factories.ts
|
|
2905
2879
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2906
2880
|
var tabbable = EditorView16.contentAttributes.of({
|
|
@@ -2957,12 +2931,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2957
2931
|
return [
|
|
2958
2932
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2959
2933
|
EditorView16.exceptionSink.of((err) => {
|
|
2960
|
-
log8.catch(err, void 0, {
|
|
2961
|
-
F: __dxlog_file11,
|
|
2962
|
-
L: 130,
|
|
2963
|
-
S: void 0,
|
|
2964
|
-
C: (f, a) => f(...a)
|
|
2965
|
-
});
|
|
2934
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2966
2935
|
}),
|
|
2967
2936
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2968
2937
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2982,6 +2951,13 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2982
2951
|
props.lineWrapping && EditorView16.lineWrapping,
|
|
2983
2952
|
props.placeholder && placeholder2(props.placeholder),
|
|
2984
2953
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2954
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
2955
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
2956
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
2957
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
2958
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
2959
|
+
// depend on being able to populate the doc themselves.
|
|
2960
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2985
2961
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2986
2962
|
props.tabbable && tabbable,
|
|
2987
2963
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -3006,8 +2982,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
3006
2982
|
preventDefault: true,
|
|
3007
2983
|
run: () => true
|
|
3008
2984
|
}
|
|
3009
|
-
].filter(
|
|
3010
|
-
].filter(
|
|
2985
|
+
].filter(isTruthy3))
|
|
2986
|
+
].filter(isTruthy3);
|
|
3011
2987
|
};
|
|
3012
2988
|
var grow = {
|
|
3013
2989
|
editor: {
|
|
@@ -3024,7 +3000,7 @@ var defaultStyles = {
|
|
|
3024
3000
|
dark: vscodeDarkStyle,
|
|
3025
3001
|
light: vscodeLightStyle
|
|
3026
3002
|
};
|
|
3027
|
-
var createThemeExtensions = ({ monospace,
|
|
3003
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
3028
3004
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
3029
3005
|
return [
|
|
3030
3006
|
baseTheme,
|
|
@@ -3039,12 +3015,17 @@ var createThemeExtensions = ({ monospace, themeMode, slots: slotsProp, syntaxHig
|
|
|
3039
3015
|
slots.content?.className && EditorView16.contentAttributes.of({
|
|
3040
3016
|
class: slots.content.className
|
|
3041
3017
|
}),
|
|
3042
|
-
slots.
|
|
3018
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
3043
3019
|
constructor(view) {
|
|
3044
|
-
|
|
3020
|
+
if (slots.scroller?.className) {
|
|
3021
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
3022
|
+
}
|
|
3023
|
+
if (scrollbarThin) {
|
|
3024
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
3025
|
+
}
|
|
3045
3026
|
}
|
|
3046
3027
|
})
|
|
3047
|
-
].filter(
|
|
3028
|
+
].filter(isTruthy3);
|
|
3048
3029
|
};
|
|
3049
3030
|
var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
3050
3031
|
const extensions = [];
|
|
@@ -4368,7 +4349,7 @@ import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lan
|
|
|
4368
4349
|
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4369
4350
|
import { languages } from "@codemirror/language-data";
|
|
4370
4351
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4371
|
-
import { isTruthy as
|
|
4352
|
+
import { isTruthy as isTruthy4 } from "@dxos/util";
|
|
4372
4353
|
|
|
4373
4354
|
// src/extensions/markdown/highlight.ts
|
|
4374
4355
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
@@ -4600,7 +4581,7 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4600
4581
|
...defaultKeymap2,
|
|
4601
4582
|
// TODO(burdon): Remove?
|
|
4602
4583
|
...completionKeymap
|
|
4603
|
-
].filter(
|
|
4584
|
+
].filter(isTruthy4))
|
|
4604
4585
|
];
|
|
4605
4586
|
};
|
|
4606
4587
|
var noFencedCodeFolding = {
|
|
@@ -5298,15 +5279,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5298
5279
|
const { state } = view;
|
|
5299
5280
|
const headerLevels = [];
|
|
5300
5281
|
const getHeaderLevels = (node, level) => {
|
|
5301
|
-
invariant4(level > 0, void 0, {
|
|
5302
|
-
F: __dxlog_file12,
|
|
5303
|
-
L: 177,
|
|
5304
|
-
S: void 0,
|
|
5305
|
-
A: [
|
|
5306
|
-
"level > 0",
|
|
5307
|
-
""
|
|
5308
|
-
]
|
|
5309
|
-
});
|
|
5282
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5310
5283
|
if (level > headerLevels.length) {
|
|
5311
5284
|
const len = headerLevels.length;
|
|
5312
5285
|
headerLevels.length = level;
|
|
@@ -5337,15 +5310,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5337
5310
|
listLevels.pop();
|
|
5338
5311
|
};
|
|
5339
5312
|
const getCurrentListLevel = () => {
|
|
5340
|
-
invariant4(listLevels.length, void 0, {
|
|
5341
|
-
F: __dxlog_file12,
|
|
5342
|
-
L: 199,
|
|
5343
|
-
S: void 0,
|
|
5344
|
-
A: [
|
|
5345
|
-
"listLevels.length",
|
|
5346
|
-
""
|
|
5347
|
-
]
|
|
5348
|
-
});
|
|
5313
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5349
5314
|
return listLevels[listLevels.length - 1];
|
|
5350
5315
|
};
|
|
5351
5316
|
const enterNode = (node) => {
|
|
@@ -5767,12 +5732,7 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5767
5732
|
(context) => {
|
|
5768
5733
|
log9.info("completion context", {
|
|
5769
5734
|
context
|
|
5770
|
-
}, {
|
|
5771
|
-
F: __dxlog_file13,
|
|
5772
|
-
L: 27,
|
|
5773
|
-
S: void 0,
|
|
5774
|
-
C: (f, a) => f(...a)
|
|
5775
|
-
});
|
|
5735
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5776
5736
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5777
5737
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5778
5738
|
return null;
|
|
@@ -6005,15 +5965,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
6005
5965
|
break;
|
|
6006
5966
|
}
|
|
6007
5967
|
case "BulletList": {
|
|
6008
|
-
invariant5(current, void 0, {
|
|
6009
|
-
F: __dxlog_file14,
|
|
6010
|
-
L: 219,
|
|
6011
|
-
S: void 0,
|
|
6012
|
-
A: [
|
|
6013
|
-
"current",
|
|
6014
|
-
""
|
|
6015
|
-
]
|
|
6016
|
-
});
|
|
5968
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
6017
5969
|
parent = current;
|
|
6018
5970
|
if (current) {
|
|
6019
5971
|
current.lineRange.to = current.node.from;
|
|
@@ -6022,15 +5974,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
6022
5974
|
break;
|
|
6023
5975
|
}
|
|
6024
5976
|
case "ListItem": {
|
|
6025
|
-
invariant5(parent, void 0, {
|
|
6026
|
-
F: __dxlog_file14,
|
|
6027
|
-
L: 228,
|
|
6028
|
-
S: void 0,
|
|
6029
|
-
A: [
|
|
6030
|
-
"parent",
|
|
6031
|
-
""
|
|
6032
|
-
]
|
|
6033
|
-
});
|
|
5977
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
6034
5978
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
6035
5979
|
const docRange = {
|
|
6036
5980
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -6064,42 +6008,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
6064
6008
|
break;
|
|
6065
6009
|
}
|
|
6066
6010
|
case "ListMark": {
|
|
6067
|
-
invariant5(current, void 0, {
|
|
6068
|
-
F: __dxlog_file14,
|
|
6069
|
-
L: 272,
|
|
6070
|
-
S: void 0,
|
|
6071
|
-
A: [
|
|
6072
|
-
"current",
|
|
6073
|
-
""
|
|
6074
|
-
]
|
|
6075
|
-
});
|
|
6011
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
6076
6012
|
current.type = "bullet";
|
|
6077
6013
|
current.contentRange.from = node.from + "- ".length;
|
|
6078
6014
|
break;
|
|
6079
6015
|
}
|
|
6080
6016
|
case "Task": {
|
|
6081
|
-
invariant5(current, void 0, {
|
|
6082
|
-
F: __dxlog_file14,
|
|
6083
|
-
L: 278,
|
|
6084
|
-
S: void 0,
|
|
6085
|
-
A: [
|
|
6086
|
-
"current",
|
|
6087
|
-
""
|
|
6088
|
-
]
|
|
6089
|
-
});
|
|
6017
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
6090
6018
|
current.type = "task";
|
|
6091
6019
|
break;
|
|
6092
6020
|
}
|
|
6093
6021
|
case "TaskMarker": {
|
|
6094
|
-
invariant5(current, void 0, {
|
|
6095
|
-
F: __dxlog_file14,
|
|
6096
|
-
L: 283,
|
|
6097
|
-
S: void 0,
|
|
6098
|
-
A: [
|
|
6099
|
-
"current",
|
|
6100
|
-
""
|
|
6101
|
-
]
|
|
6102
|
-
});
|
|
6022
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
6103
6023
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
6104
6024
|
break;
|
|
6105
6025
|
}
|
|
@@ -6107,29 +6027,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
6107
6027
|
},
|
|
6108
6028
|
leave: (node) => {
|
|
6109
6029
|
if (node.name === "BulletList") {
|
|
6110
|
-
invariant5(parent, void 0, {
|
|
6111
|
-
F: __dxlog_file14,
|
|
6112
|
-
L: 291,
|
|
6113
|
-
S: void 0,
|
|
6114
|
-
A: [
|
|
6115
|
-
"parent",
|
|
6116
|
-
""
|
|
6117
|
-
]
|
|
6118
|
-
});
|
|
6030
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
6119
6031
|
prevSiblings[level--] = void 0;
|
|
6120
6032
|
parent = parent.parent;
|
|
6121
6033
|
}
|
|
6122
6034
|
}
|
|
6123
6035
|
});
|
|
6124
|
-
invariant5(tree, void 0, {
|
|
6125
|
-
F: __dxlog_file14,
|
|
6126
|
-
L: 298,
|
|
6127
|
-
S: void 0,
|
|
6128
|
-
A: [
|
|
6129
|
-
"tree",
|
|
6130
|
-
""
|
|
6131
|
-
]
|
|
6132
|
-
});
|
|
6036
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
6133
6037
|
return tree;
|
|
6134
6038
|
};
|
|
6135
6039
|
return [
|
|
@@ -6571,35 +6475,20 @@ var editor = () => [
|
|
|
6571
6475
|
text: insert.toString(),
|
|
6572
6476
|
length: insert.length
|
|
6573
6477
|
}
|
|
6574
|
-
}, {
|
|
6575
|
-
F: __dxlog_file15,
|
|
6576
|
-
L: 164,
|
|
6577
|
-
S: void 0,
|
|
6578
|
-
C: (f, a) => f(...a)
|
|
6579
|
-
});
|
|
6478
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6580
6479
|
}
|
|
6581
6480
|
});
|
|
6582
6481
|
if (changes.length > 0) {
|
|
6583
6482
|
log10("modified,", {
|
|
6584
6483
|
changes
|
|
6585
|
-
}, {
|
|
6586
|
-
F: __dxlog_file15,
|
|
6587
|
-
L: 175,
|
|
6588
|
-
S: void 0,
|
|
6589
|
-
C: (f, a) => f(...a)
|
|
6590
|
-
});
|
|
6484
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6591
6485
|
return [
|
|
6592
6486
|
{
|
|
6593
6487
|
changes
|
|
6594
6488
|
}
|
|
6595
6489
|
];
|
|
6596
6490
|
} else if (cancel) {
|
|
6597
|
-
log10("cancel", void 0, {
|
|
6598
|
-
F: __dxlog_file15,
|
|
6599
|
-
L: 178,
|
|
6600
|
-
S: void 0,
|
|
6601
|
-
C: (f, a) => f(...a)
|
|
6602
|
-
});
|
|
6491
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6603
6492
|
return [];
|
|
6604
6493
|
}
|
|
6605
6494
|
return tr;
|
|
@@ -6773,7 +6662,7 @@ var decorations = () => [
|
|
|
6773
6662
|
marginBottom: "2px"
|
|
6774
6663
|
},
|
|
6775
6664
|
".cm-list-item-focused": {
|
|
6776
|
-
borderColor: "var(--color-
|
|
6665
|
+
borderColor: "var(--color-focus-ring-subtle)"
|
|
6777
6666
|
},
|
|
6778
6667
|
"&:focus-within .cm-list-item-selected": {
|
|
6779
6668
|
borderColor: "var(--color-separator)"
|
|
@@ -7040,12 +6929,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
7040
6929
|
});
|
|
7041
6930
|
};
|
|
7042
6931
|
|
|
6932
|
+
// src/extensions/snippets.ts
|
|
6933
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
6934
|
+
var defaultItems = [
|
|
6935
|
+
"hello world!",
|
|
6936
|
+
"this is a test.",
|
|
6937
|
+
"this is [DXOS](https://dxos.org)"
|
|
6938
|
+
];
|
|
6939
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
6940
|
+
let timer;
|
|
6941
|
+
let index = 0;
|
|
6942
|
+
return [
|
|
6943
|
+
keymap12.of([
|
|
6944
|
+
{
|
|
6945
|
+
// Reset.
|
|
6946
|
+
key: "alt-meta-'",
|
|
6947
|
+
run: () => {
|
|
6948
|
+
clearTimeout(timer);
|
|
6949
|
+
index = 0;
|
|
6950
|
+
return true;
|
|
6951
|
+
}
|
|
6952
|
+
},
|
|
6953
|
+
{
|
|
6954
|
+
// Next snippet.
|
|
6955
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
6956
|
+
key: "Shift-Meta-'",
|
|
6957
|
+
run: (view) => {
|
|
6958
|
+
clearTimeout(timer);
|
|
6959
|
+
const text = items[index++];
|
|
6960
|
+
if (index === items?.length) {
|
|
6961
|
+
index = 0;
|
|
6962
|
+
}
|
|
6963
|
+
let offset = 0;
|
|
6964
|
+
const insert = (delayMs = 0) => {
|
|
6965
|
+
timer = setTimeout(() => {
|
|
6966
|
+
const pos = view.state.selection.main.head;
|
|
6967
|
+
view.dispatch({
|
|
6968
|
+
changes: {
|
|
6969
|
+
from: pos,
|
|
6970
|
+
insert: text[offset++]
|
|
6971
|
+
},
|
|
6972
|
+
selection: {
|
|
6973
|
+
anchor: pos + 1
|
|
6974
|
+
}
|
|
6975
|
+
});
|
|
6976
|
+
if (offset < text.length) {
|
|
6977
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
6978
|
+
}
|
|
6979
|
+
}, delayMs);
|
|
6980
|
+
};
|
|
6981
|
+
insert();
|
|
6982
|
+
return true;
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
])
|
|
6986
|
+
];
|
|
6987
|
+
};
|
|
6988
|
+
|
|
7043
6989
|
// src/extensions/submit.ts
|
|
7044
6990
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
7045
|
-
import { keymap as
|
|
6991
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
7046
6992
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
7047
6993
|
return [
|
|
7048
|
-
Prec6.highest(
|
|
6994
|
+
Prec6.highest(keymap13.of([
|
|
7049
6995
|
{
|
|
7050
6996
|
key: "Enter",
|
|
7051
6997
|
preventDefault: true,
|
|
@@ -7371,36 +7317,46 @@ var fader = (options = {}) => {
|
|
|
7371
7317
|
];
|
|
7372
7318
|
};
|
|
7373
7319
|
|
|
7374
|
-
// src/extensions/tags/
|
|
7320
|
+
// src/extensions/tags/typewriter.ts
|
|
7375
7321
|
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7376
7322
|
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7377
7323
|
import { Domino as Domino3 } from "@dxos/ui";
|
|
7378
|
-
var
|
|
7379
|
-
var
|
|
7324
|
+
var typewriterBypass = Annotation3.define();
|
|
7325
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7380
7326
|
var CURSOR_LINGER = 3e3;
|
|
7381
|
-
var
|
|
7382
|
-
|
|
7383
|
-
|
|
7327
|
+
var FRAME_BUDGET_MS = 4;
|
|
7328
|
+
var CHARS_PER_FRAME = 5;
|
|
7329
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7330
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7331
|
+
var typewriter = (options = {}) => {
|
|
7384
7332
|
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7333
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7334
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7335
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7385
7336
|
const suppressAppend = StateEffect11.define();
|
|
7386
7337
|
const insertChunk = StateEffect11.define();
|
|
7387
7338
|
const bufferField = StateField13.define({
|
|
7388
7339
|
create: () => ({
|
|
7389
7340
|
text: "",
|
|
7341
|
+
head: 0,
|
|
7390
7342
|
insertAt: 0
|
|
7391
7343
|
}),
|
|
7392
7344
|
update: (value, tr) => {
|
|
7393
|
-
let { text, insertAt } = value;
|
|
7345
|
+
let { text, head, insertAt } = value;
|
|
7394
7346
|
for (const effect of tr.effects) {
|
|
7395
7347
|
if (effect.is(suppressAppend)) {
|
|
7396
|
-
text
|
|
7397
|
-
if (text.length === effect.value.text.length) {
|
|
7348
|
+
if (text.length === head) {
|
|
7398
7349
|
insertAt = effect.value.from;
|
|
7399
7350
|
}
|
|
7351
|
+
text += effect.value.text;
|
|
7400
7352
|
}
|
|
7401
7353
|
if (effect.is(insertChunk)) {
|
|
7402
|
-
|
|
7354
|
+
head += effect.value.text.length;
|
|
7403
7355
|
insertAt = effect.value.from + effect.value.text.length;
|
|
7356
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7357
|
+
text = text.slice(head);
|
|
7358
|
+
head = 0;
|
|
7359
|
+
}
|
|
7404
7360
|
}
|
|
7405
7361
|
}
|
|
7406
7362
|
if (tr.docChanged) {
|
|
@@ -7415,6 +7371,7 @@ var wire = (options = {}) => {
|
|
|
7415
7371
|
if (isReset) {
|
|
7416
7372
|
return {
|
|
7417
7373
|
text: "",
|
|
7374
|
+
head: 0,
|
|
7418
7375
|
insertAt: 0
|
|
7419
7376
|
};
|
|
7420
7377
|
}
|
|
@@ -7424,6 +7381,7 @@ var wire = (options = {}) => {
|
|
|
7424
7381
|
}
|
|
7425
7382
|
return {
|
|
7426
7383
|
text,
|
|
7384
|
+
head,
|
|
7427
7385
|
insertAt
|
|
7428
7386
|
};
|
|
7429
7387
|
}
|
|
@@ -7432,7 +7390,7 @@ var wire = (options = {}) => {
|
|
|
7432
7390
|
if (!tr.docChanged) {
|
|
7433
7391
|
return tr;
|
|
7434
7392
|
}
|
|
7435
|
-
if (tr.annotation(
|
|
7393
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7436
7394
|
return tr;
|
|
7437
7395
|
}
|
|
7438
7396
|
let appendedText = "";
|
|
@@ -7461,40 +7419,82 @@ var wire = (options = {}) => {
|
|
|
7461
7419
|
});
|
|
7462
7420
|
const drainPlugin = ViewPlugin21.fromClass(class {
|
|
7463
7421
|
view;
|
|
7464
|
-
|
|
7465
|
-
|
|
7422
|
+
_raf;
|
|
7423
|
+
_activeStreamTag = null;
|
|
7466
7424
|
constructor(view) {
|
|
7467
7425
|
this.view = view;
|
|
7468
|
-
this.#start();
|
|
7469
7426
|
}
|
|
7470
7427
|
update(update2) {
|
|
7471
|
-
const
|
|
7472
|
-
|
|
7473
|
-
|
|
7428
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7429
|
+
const pending = text.length - head;
|
|
7430
|
+
if (pending === 0) {
|
|
7431
|
+
this._activeStreamTag = null;
|
|
7474
7432
|
}
|
|
7475
|
-
if (
|
|
7476
|
-
this
|
|
7433
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7434
|
+
this._start();
|
|
7477
7435
|
}
|
|
7478
7436
|
}
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7437
|
+
_start() {
|
|
7438
|
+
queueMicrotask(() => {
|
|
7439
|
+
this.view.dispatch({
|
|
7440
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7441
|
+
annotations: typewriterBypass.of(true)
|
|
7442
|
+
});
|
|
7443
|
+
});
|
|
7444
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7445
|
+
}
|
|
7446
|
+
_tick = () => {
|
|
7447
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7448
|
+
const pending = text.length - head;
|
|
7449
|
+
if (pending === 0) {
|
|
7450
|
+
this.view.dispatch({
|
|
7451
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7452
|
+
annotations: typewriterBypass.of(true)
|
|
7453
|
+
});
|
|
7454
|
+
this._raf = void 0;
|
|
7455
|
+
return;
|
|
7456
|
+
}
|
|
7457
|
+
if (pending > flushThreshold) {
|
|
7458
|
+
const chunk = text.slice(head);
|
|
7459
|
+
this._activeStreamTag = null;
|
|
7460
|
+
this.view.dispatch({
|
|
7461
|
+
changes: {
|
|
7462
|
+
from: insertAt,
|
|
7463
|
+
insert: chunk
|
|
7464
|
+
},
|
|
7465
|
+
effects: insertChunk.of({
|
|
7466
|
+
from: insertAt,
|
|
7467
|
+
text: chunk
|
|
7468
|
+
})
|
|
7469
|
+
});
|
|
7470
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7471
|
+
return;
|
|
7472
|
+
}
|
|
7473
|
+
const startTime = performance.now();
|
|
7474
|
+
let pos = head;
|
|
7475
|
+
let activeTag = this._activeStreamTag;
|
|
7476
|
+
let charsEmitted = 0;
|
|
7477
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7478
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7488
7479
|
if (result.count === 0) {
|
|
7489
|
-
|
|
7480
|
+
break;
|
|
7481
|
+
}
|
|
7482
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7483
|
+
break;
|
|
7490
7484
|
}
|
|
7491
7485
|
if (result.enterTag) {
|
|
7492
|
-
|
|
7486
|
+
activeTag = result.enterTag;
|
|
7493
7487
|
}
|
|
7494
7488
|
if (result.exitTag) {
|
|
7495
|
-
|
|
7489
|
+
activeTag = null;
|
|
7496
7490
|
}
|
|
7497
|
-
|
|
7491
|
+
pos += result.count;
|
|
7492
|
+
charsEmitted += result.count;
|
|
7493
|
+
}
|
|
7494
|
+
const totalCount = pos - head;
|
|
7495
|
+
if (totalCount > 0) {
|
|
7496
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7497
|
+
this._activeStreamTag = activeTag;
|
|
7498
7498
|
this.view.dispatch({
|
|
7499
7499
|
changes: {
|
|
7500
7500
|
from: insertAt,
|
|
@@ -7505,20 +7505,23 @@ var wire = (options = {}) => {
|
|
|
7505
7505
|
text: chunk
|
|
7506
7506
|
})
|
|
7507
7507
|
});
|
|
7508
|
-
}
|
|
7509
|
-
|
|
7508
|
+
}
|
|
7509
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7510
|
+
};
|
|
7510
7511
|
destroy() {
|
|
7511
|
-
|
|
7512
|
+
if (this._raf !== void 0) {
|
|
7513
|
+
cancelAnimationFrame(this._raf);
|
|
7514
|
+
}
|
|
7512
7515
|
}
|
|
7513
7516
|
});
|
|
7514
7517
|
return [
|
|
7515
7518
|
bufferField,
|
|
7516
7519
|
filter,
|
|
7517
7520
|
drainPlugin,
|
|
7518
|
-
options.cursor &&
|
|
7521
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7519
7522
|
].filter(Boolean);
|
|
7520
7523
|
};
|
|
7521
|
-
var
|
|
7524
|
+
var typewriterCursor = (bufferField) => {
|
|
7522
7525
|
const hideCursor = StateEffect11.define();
|
|
7523
7526
|
const visibilityField = StateField13.define({
|
|
7524
7527
|
create: () => ({
|
|
@@ -7527,8 +7530,9 @@ var wireCursor = (bufferField) => {
|
|
|
7527
7530
|
lastNonWsAt: 0
|
|
7528
7531
|
}),
|
|
7529
7532
|
update: (value, tr) => {
|
|
7530
|
-
const { text, insertAt } = tr.state.field(bufferField);
|
|
7531
|
-
|
|
7533
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7534
|
+
const pending = text.length - head;
|
|
7535
|
+
if (pending > 0) {
|
|
7532
7536
|
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7533
7537
|
if (tr.docChanged) {
|
|
7534
7538
|
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
@@ -7562,8 +7566,8 @@ var wireCursor = (bufferField) => {
|
|
|
7562
7566
|
if (!visible) {
|
|
7563
7567
|
return Decoration15.none;
|
|
7564
7568
|
}
|
|
7565
|
-
const { text } = tr.state.field(bufferField);
|
|
7566
|
-
const cursorAt = text.length >
|
|
7569
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7570
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7567
7571
|
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7568
7572
|
return Decoration15.set([
|
|
7569
7573
|
Decoration15.widget({
|
|
@@ -7576,27 +7580,28 @@ var wireCursor = (bufferField) => {
|
|
|
7576
7580
|
});
|
|
7577
7581
|
const timerPlugin = ViewPlugin21.fromClass(class {
|
|
7578
7582
|
view;
|
|
7579
|
-
|
|
7583
|
+
_timer;
|
|
7580
7584
|
constructor(view) {
|
|
7581
7585
|
this.view = view;
|
|
7582
7586
|
}
|
|
7583
7587
|
update(update2) {
|
|
7584
|
-
const { text } = update2.state.field(bufferField);
|
|
7588
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7585
7589
|
const { visible } = update2.state.field(visibilityField);
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
this
|
|
7589
|
-
|
|
7590
|
-
|
|
7590
|
+
const pending = text.length - head;
|
|
7591
|
+
if (pending > 0) {
|
|
7592
|
+
clearTimeout(this._timer);
|
|
7593
|
+
this._timer = void 0;
|
|
7594
|
+
} else if (visible && this._timer === void 0) {
|
|
7595
|
+
this._timer = setTimeout(() => {
|
|
7591
7596
|
this.view.dispatch({
|
|
7592
7597
|
effects: hideCursor.of(null)
|
|
7593
7598
|
});
|
|
7594
|
-
this
|
|
7599
|
+
this._timer = void 0;
|
|
7595
7600
|
}, CURSOR_LINGER);
|
|
7596
7601
|
}
|
|
7597
7602
|
}
|
|
7598
7603
|
destroy() {
|
|
7599
|
-
clearTimeout(this
|
|
7604
|
+
clearTimeout(this._timer);
|
|
7600
7605
|
}
|
|
7601
7606
|
});
|
|
7602
7607
|
return [
|
|
@@ -7605,7 +7610,12 @@ var wireCursor = (bufferField) => {
|
|
|
7605
7610
|
timerPlugin
|
|
7606
7611
|
];
|
|
7607
7612
|
};
|
|
7608
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7613
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7614
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7615
|
+
// the blink animation isn't restarted on every transaction.
|
|
7616
|
+
eq(other) {
|
|
7617
|
+
return other instanceof _CursorWidget;
|
|
7618
|
+
}
|
|
7609
7619
|
toDOM() {
|
|
7610
7620
|
const inner = Domino3.of("span").text("\u2217").style({
|
|
7611
7621
|
animation: "blink 1s infinite",
|
|
@@ -7617,35 +7627,37 @@ var CursorWidget = class extends WidgetType9 {
|
|
|
7617
7627
|
}
|
|
7618
7628
|
};
|
|
7619
7629
|
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7630
|
+
var TAG_NAME_PROBE = 64;
|
|
7620
7631
|
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7621
|
-
var flushable = (buffer, streamingTags, activeStreamTag) => {
|
|
7622
|
-
if (buffer.length
|
|
7632
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7633
|
+
if (start >= buffer.length) {
|
|
7623
7634
|
return {
|
|
7624
7635
|
count: 0
|
|
7625
7636
|
};
|
|
7626
7637
|
}
|
|
7627
7638
|
if (activeStreamTag) {
|
|
7628
7639
|
const closeTag = `</${activeStreamTag}>`;
|
|
7629
|
-
if (buffer.startsWith(closeTag)) {
|
|
7640
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7630
7641
|
return {
|
|
7631
7642
|
count: closeTag.length,
|
|
7632
7643
|
exitTag: true
|
|
7633
7644
|
};
|
|
7634
7645
|
}
|
|
7635
|
-
if (buffer[
|
|
7646
|
+
if (buffer[start] === "<") {
|
|
7636
7647
|
return {
|
|
7637
|
-
count: xmlElementLength(buffer)
|
|
7648
|
+
count: xmlElementLength(buffer, start)
|
|
7638
7649
|
};
|
|
7639
7650
|
}
|
|
7640
7651
|
return {
|
|
7641
7652
|
count: 1
|
|
7642
7653
|
};
|
|
7643
7654
|
}
|
|
7644
|
-
const ch = buffer[
|
|
7655
|
+
const ch = buffer[start];
|
|
7645
7656
|
if (ch === "<") {
|
|
7646
|
-
const
|
|
7657
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7658
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7647
7659
|
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7648
|
-
const close = buffer.indexOf(">");
|
|
7660
|
+
const close = buffer.indexOf(">", start);
|
|
7649
7661
|
if (close === -1) {
|
|
7650
7662
|
return {
|
|
7651
7663
|
count: 0
|
|
@@ -7653,62 +7665,64 @@ var flushable = (buffer, streamingTags, activeStreamTag) => {
|
|
|
7653
7665
|
}
|
|
7654
7666
|
if (buffer[close - 1] === "/") {
|
|
7655
7667
|
return {
|
|
7656
|
-
count: close + 1
|
|
7668
|
+
count: close + 1 - start
|
|
7657
7669
|
};
|
|
7658
7670
|
}
|
|
7659
7671
|
return {
|
|
7660
|
-
count: close + 1,
|
|
7672
|
+
count: close + 1 - start,
|
|
7661
7673
|
enterTag: nameMatch[1]
|
|
7662
7674
|
};
|
|
7663
7675
|
}
|
|
7664
7676
|
return {
|
|
7665
|
-
count: xmlElementLength(buffer)
|
|
7677
|
+
count: xmlElementLength(buffer, start)
|
|
7666
7678
|
};
|
|
7667
7679
|
}
|
|
7668
|
-
if (ch === "!" && buffer.length > 1 && buffer[1] === "[") {
|
|
7680
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7669
7681
|
return {
|
|
7670
|
-
count: linkLength(buffer, 1)
|
|
7682
|
+
count: linkLength(buffer, start, start + 1)
|
|
7671
7683
|
};
|
|
7672
7684
|
}
|
|
7673
7685
|
if (ch === "[") {
|
|
7674
7686
|
return {
|
|
7675
|
-
count: linkLength(buffer,
|
|
7687
|
+
count: linkLength(buffer, start, start)
|
|
7676
7688
|
};
|
|
7677
7689
|
}
|
|
7678
7690
|
return {
|
|
7679
7691
|
count: 1
|
|
7680
7692
|
};
|
|
7681
7693
|
};
|
|
7682
|
-
var xmlElementLength = (buffer) => {
|
|
7683
|
-
const close = buffer.indexOf(">");
|
|
7694
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7695
|
+
const close = buffer.indexOf(">", start);
|
|
7684
7696
|
if (close === -1) {
|
|
7685
7697
|
return 0;
|
|
7686
7698
|
}
|
|
7687
7699
|
if (buffer[close - 1] === "/") {
|
|
7688
|
-
return close + 1;
|
|
7700
|
+
return close + 1 - start;
|
|
7689
7701
|
}
|
|
7690
|
-
if (buffer[1] === "/") {
|
|
7691
|
-
return close + 1;
|
|
7702
|
+
if (buffer[start + 1] === "/") {
|
|
7703
|
+
return close + 1 - start;
|
|
7692
7704
|
}
|
|
7693
|
-
const
|
|
7705
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7706
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7694
7707
|
if (!nameMatch) {
|
|
7695
7708
|
return 1;
|
|
7696
7709
|
}
|
|
7697
7710
|
const tagName = nameMatch[1];
|
|
7698
7711
|
let depth = 0;
|
|
7699
7712
|
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7713
|
+
tagPattern.lastIndex = start;
|
|
7700
7714
|
let match;
|
|
7701
7715
|
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7702
7716
|
const isSelfClosing = match[0].endsWith("/>");
|
|
7703
7717
|
const isClosing = match[1] === "/";
|
|
7704
7718
|
if (isSelfClosing) {
|
|
7705
7719
|
if (depth === 0) {
|
|
7706
|
-
return match.index + match[0].length;
|
|
7720
|
+
return match.index + match[0].length - start;
|
|
7707
7721
|
}
|
|
7708
7722
|
} else if (isClosing) {
|
|
7709
7723
|
depth--;
|
|
7710
7724
|
if (depth === 0) {
|
|
7711
|
-
return match.index + match[0].length;
|
|
7725
|
+
return match.index + match[0].length - start;
|
|
7712
7726
|
}
|
|
7713
7727
|
} else {
|
|
7714
7728
|
depth++;
|
|
@@ -7716,8 +7730,8 @@ var xmlElementLength = (buffer) => {
|
|
|
7716
7730
|
}
|
|
7717
7731
|
return 0;
|
|
7718
7732
|
};
|
|
7719
|
-
var linkLength = (buffer,
|
|
7720
|
-
const bracketClose = buffer.indexOf("]",
|
|
7733
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7734
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7721
7735
|
if (bracketClose === -1) {
|
|
7722
7736
|
return 0;
|
|
7723
7737
|
}
|
|
@@ -7731,13 +7745,179 @@ var linkLength = (buffer, offset) => {
|
|
|
7731
7745
|
if (parenClose === -1) {
|
|
7732
7746
|
return 0;
|
|
7733
7747
|
}
|
|
7734
|
-
return parenClose + 1;
|
|
7748
|
+
return parenClose + 1 - start;
|
|
7749
|
+
};
|
|
7750
|
+
|
|
7751
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7752
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7753
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7754
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7755
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7756
|
+
class: lineClass
|
|
7757
|
+
}) : void 0;
|
|
7758
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7759
|
+
class: contentClass
|
|
7760
|
+
}) : void 0;
|
|
7761
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7762
|
+
const buildDecorations5 = (view) => {
|
|
7763
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7764
|
+
if (!text.includes(`<${tag}`)) {
|
|
7765
|
+
return Decoration16.none;
|
|
7766
|
+
}
|
|
7767
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7768
|
+
const ranges = [];
|
|
7769
|
+
tree.iterate({
|
|
7770
|
+
enter: (node) => {
|
|
7771
|
+
if (node.type.name !== "Element") {
|
|
7772
|
+
return;
|
|
7773
|
+
}
|
|
7774
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7775
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7776
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7777
|
+
if (!openTag || !tagNameNode) {
|
|
7778
|
+
return;
|
|
7779
|
+
}
|
|
7780
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7781
|
+
return;
|
|
7782
|
+
}
|
|
7783
|
+
const contentFrom = openTag.to;
|
|
7784
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7785
|
+
if (hideDecoration) {
|
|
7786
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7787
|
+
if (closeTag) {
|
|
7788
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7789
|
+
}
|
|
7790
|
+
}
|
|
7791
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7792
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7793
|
+
}
|
|
7794
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7795
|
+
let pos = contentFrom;
|
|
7796
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7797
|
+
const line = view.state.doc.lineAt(pos);
|
|
7798
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7799
|
+
if (line.to >= contentTo) {
|
|
7800
|
+
break;
|
|
7801
|
+
}
|
|
7802
|
+
pos = line.to + 1;
|
|
7803
|
+
}
|
|
7804
|
+
}
|
|
7805
|
+
}
|
|
7806
|
+
});
|
|
7807
|
+
return Decoration16.set(ranges, true);
|
|
7808
|
+
};
|
|
7809
|
+
return ViewPlugin22.fromClass(class {
|
|
7810
|
+
decorations;
|
|
7811
|
+
constructor(view) {
|
|
7812
|
+
this.decorations = buildDecorations5(view);
|
|
7813
|
+
}
|
|
7814
|
+
update(update2) {
|
|
7815
|
+
if (update2.docChanged) {
|
|
7816
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7817
|
+
}
|
|
7818
|
+
}
|
|
7819
|
+
}, {
|
|
7820
|
+
decorations: (instance) => instance.decorations
|
|
7821
|
+
});
|
|
7822
|
+
};
|
|
7823
|
+
|
|
7824
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7825
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7826
|
+
import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
|
|
7827
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7828
|
+
"OpenTag",
|
|
7829
|
+
"CloseTag",
|
|
7830
|
+
"SelfClosingTag",
|
|
7831
|
+
"MismatchedCloseTag"
|
|
7832
|
+
]);
|
|
7833
|
+
var xmlElementMark = Decoration17.mark({
|
|
7834
|
+
class: "cm-xml-element"
|
|
7835
|
+
});
|
|
7836
|
+
var xmlTagMark = Decoration17.mark({
|
|
7837
|
+
class: "cm-xml-tag"
|
|
7838
|
+
});
|
|
7839
|
+
var xmlContentMark = Decoration17.mark({
|
|
7840
|
+
class: "cm-xml-content"
|
|
7841
|
+
});
|
|
7842
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7843
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7844
|
+
const buildDecorations5 = (view) => {
|
|
7845
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7846
|
+
if (!text.includes("<")) {
|
|
7847
|
+
return Decoration17.none;
|
|
7848
|
+
}
|
|
7849
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7850
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7851
|
+
const ranges = [];
|
|
7852
|
+
tree.iterate({
|
|
7853
|
+
enter: (node) => {
|
|
7854
|
+
const name = node.type.name;
|
|
7855
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
7856
|
+
if (skipSet) {
|
|
7857
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
7858
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7859
|
+
return false;
|
|
7860
|
+
}
|
|
7861
|
+
}
|
|
7862
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7863
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7864
|
+
return;
|
|
7865
|
+
}
|
|
7866
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
7867
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7868
|
+
return;
|
|
7869
|
+
}
|
|
7870
|
+
if (name === "Element" && node.from < node.to) {
|
|
7871
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7872
|
+
if (openTag && skipSet) {
|
|
7873
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
7874
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7875
|
+
return false;
|
|
7876
|
+
}
|
|
7877
|
+
}
|
|
7878
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7879
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7880
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
7881
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
7882
|
+
}
|
|
7883
|
+
}
|
|
7884
|
+
}
|
|
7885
|
+
});
|
|
7886
|
+
return Decoration17.set(ranges, true);
|
|
7887
|
+
};
|
|
7888
|
+
return [
|
|
7889
|
+
ViewPlugin23.fromClass(class {
|
|
7890
|
+
decorations;
|
|
7891
|
+
constructor(view) {
|
|
7892
|
+
this.decorations = buildDecorations5(view);
|
|
7893
|
+
}
|
|
7894
|
+
update(update2) {
|
|
7895
|
+
if (update2.docChanged) {
|
|
7896
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7897
|
+
}
|
|
7898
|
+
}
|
|
7899
|
+
}, {
|
|
7900
|
+
decorations: (instance) => instance.decorations
|
|
7901
|
+
}),
|
|
7902
|
+
EditorView31.baseTheme({
|
|
7903
|
+
".cm-xml-element": {
|
|
7904
|
+
backgroundColor: "var(--color-current-surface)",
|
|
7905
|
+
borderRadius: "0.25rem",
|
|
7906
|
+
padding: "0.25rem"
|
|
7907
|
+
},
|
|
7908
|
+
".cm-xml-tag": {
|
|
7909
|
+
color: "var(--color-blue-500)",
|
|
7910
|
+
fontFamily: "var(--font-mono)"
|
|
7911
|
+
},
|
|
7912
|
+
".cm-xml-content": {}
|
|
7913
|
+
})
|
|
7914
|
+
];
|
|
7735
7915
|
};
|
|
7736
7916
|
|
|
7737
7917
|
// src/extensions/tags/xml-tags.ts
|
|
7738
7918
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7739
7919
|
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
|
|
7740
|
-
import { Decoration as
|
|
7920
|
+
import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7741
7921
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7742
7922
|
import { log as log11 } from "@dxos/log";
|
|
7743
7923
|
import { Domino as Domino4 } from "@dxos/ui";
|
|
@@ -7746,15 +7926,7 @@ import { Domino as Domino4 } from "@dxos/ui";
|
|
|
7746
7926
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7747
7927
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7748
7928
|
var nodeToJson = (state, node) => {
|
|
7749
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7750
|
-
F: __dxlog_file16,
|
|
7751
|
-
L: 18,
|
|
7752
|
-
S: void 0,
|
|
7753
|
-
A: [
|
|
7754
|
-
"node.type.name === 'Element'",
|
|
7755
|
-
"'Node is not an Element'"
|
|
7756
|
-
]
|
|
7757
|
-
});
|
|
7929
|
+
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'"] });
|
|
7758
7930
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7759
7931
|
if (openTag) {
|
|
7760
7932
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7786,13 +7958,23 @@ var nodeToJson = (state, node) => {
|
|
|
7786
7958
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7787
7959
|
const children = [];
|
|
7788
7960
|
let child = node.node.firstChild;
|
|
7961
|
+
const appendText = (raw) => {
|
|
7962
|
+
if (raw.length === 0) {
|
|
7963
|
+
return;
|
|
7964
|
+
}
|
|
7965
|
+
const last = children[children.length - 1];
|
|
7966
|
+
if (typeof last === "string") {
|
|
7967
|
+
children[children.length - 1] = last + raw;
|
|
7968
|
+
} else {
|
|
7969
|
+
children.push(raw);
|
|
7970
|
+
}
|
|
7971
|
+
};
|
|
7789
7972
|
while (child) {
|
|
7790
7973
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7791
7974
|
if (child.type.name === "Text") {
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
}
|
|
7975
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
7976
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
7977
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7796
7978
|
} else if (child.type.name === "Element") {
|
|
7797
7979
|
const data = nodeToJson(state, child);
|
|
7798
7980
|
if (data) {
|
|
@@ -7802,13 +7984,48 @@ var nodeToJson = (state, node) => {
|
|
|
7802
7984
|
}
|
|
7803
7985
|
child = child.nextSibling;
|
|
7804
7986
|
}
|
|
7987
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7988
|
+
children[0] = children[0].trimStart();
|
|
7989
|
+
}
|
|
7805
7990
|
if (children.length > 0) {
|
|
7806
|
-
|
|
7991
|
+
const lastIndex = children.length - 1;
|
|
7992
|
+
const last = children[lastIndex];
|
|
7993
|
+
if (typeof last === "string") {
|
|
7994
|
+
children[lastIndex] = last.trimEnd();
|
|
7995
|
+
}
|
|
7996
|
+
}
|
|
7997
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
7998
|
+
if (trimmed.length > 0) {
|
|
7999
|
+
tag.children = trimmed;
|
|
7807
8000
|
}
|
|
7808
8001
|
}
|
|
7809
8002
|
return tag;
|
|
7810
8003
|
}
|
|
7811
8004
|
};
|
|
8005
|
+
var XML_NAMED_ENTITIES = {
|
|
8006
|
+
"<": "<",
|
|
8007
|
+
">": ">",
|
|
8008
|
+
"&": "&",
|
|
8009
|
+
""": '"',
|
|
8010
|
+
"'": "'"
|
|
8011
|
+
};
|
|
8012
|
+
var decodeXmlEntity = (raw) => {
|
|
8013
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
8014
|
+
if (named !== void 0) {
|
|
8015
|
+
return named;
|
|
8016
|
+
}
|
|
8017
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
8018
|
+
if (numeric) {
|
|
8019
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
8020
|
+
if (Number.isFinite(code)) {
|
|
8021
|
+
try {
|
|
8022
|
+
return String.fromCodePoint(code);
|
|
8023
|
+
} catch {
|
|
8024
|
+
}
|
|
8025
|
+
}
|
|
8026
|
+
}
|
|
8027
|
+
return raw;
|
|
8028
|
+
};
|
|
7812
8029
|
|
|
7813
8030
|
// src/extensions/tags/xml-tags.ts
|
|
7814
8031
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
@@ -7846,12 +8063,7 @@ var widgetStateMapStateField = StateField14.define({
|
|
|
7846
8063
|
log11("widget updated", {
|
|
7847
8064
|
id,
|
|
7848
8065
|
value
|
|
7849
|
-
}, {
|
|
7850
|
-
F: __dxlog_file17,
|
|
7851
|
-
L: 184,
|
|
7852
|
-
S: void 0,
|
|
7853
|
-
C: (f, a) => f(...a)
|
|
7854
|
-
});
|
|
8066
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7855
8067
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7856
8068
|
return {
|
|
7857
8069
|
...map,
|
|
@@ -7862,25 +8074,16 @@ var widgetStateMapStateField = StateField14.define({
|
|
|
7862
8074
|
return map;
|
|
7863
8075
|
}
|
|
7864
8076
|
});
|
|
7865
|
-
var
|
|
7866
|
-
var xmlTags = ({ registry, setWidgets, bookmarks: bookmarks2, paragraphToWidgetGapRem } = {}) => {
|
|
8077
|
+
var xmlTags = ({ registry, setWidgets, bookmarks: bookmarks2 } = {}) => {
|
|
7867
8078
|
const notifier = createWidgetMap(setWidgets);
|
|
7868
8079
|
const widgetDecorationsField = createWidgetDecorationsField(registry, notifier);
|
|
7869
|
-
const paragraphGapTheme = paragraphToWidgetGapRem != null && paragraphToWidgetGapRem > 0 ? EditorView31.baseTheme({
|
|
7870
|
-
[`& .cm-content > .cm-line:not(:has([${XML_WIDGET_DATA_ATTR}])) + .cm-line:has([${XML_WIDGET_DATA_ATTR}])`]: {
|
|
7871
|
-
marginTop: `${paragraphToWidgetGapRem}rem`
|
|
7872
|
-
}
|
|
7873
|
-
}) : null;
|
|
7874
8080
|
return [
|
|
7875
8081
|
widgetContextStateField,
|
|
7876
8082
|
widgetStateMapStateField,
|
|
7877
8083
|
widgetDecorationsField,
|
|
7878
8084
|
createWidgetUpdatePlugin(widgetDecorationsField, notifier),
|
|
7879
8085
|
createNavigationEffectPlugin(widgetDecorationsField, bookmarks2),
|
|
7880
|
-
bookmarks2?.length ? Prec7.highest(keyHandlers) : []
|
|
7881
|
-
...paragraphGapTheme ? [
|
|
7882
|
-
paragraphGapTheme
|
|
7883
|
-
] : []
|
|
8086
|
+
bookmarks2?.length ? Prec7.highest(keyHandlers) : []
|
|
7884
8087
|
];
|
|
7885
8088
|
};
|
|
7886
8089
|
var createWidgetMap = (setWidgets) => {
|
|
@@ -7890,12 +8093,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7890
8093
|
log11("widget mounted", {
|
|
7891
8094
|
id: state.id,
|
|
7892
8095
|
tag: state.props._tag
|
|
7893
|
-
}, {
|
|
7894
|
-
F: __dxlog_file17,
|
|
7895
|
-
L: 261,
|
|
7896
|
-
S: void 0,
|
|
7897
|
-
C: (f, a) => f(...a)
|
|
7898
|
-
});
|
|
8096
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7899
8097
|
widgets.set(state.id, state);
|
|
7900
8098
|
setWidgets?.([
|
|
7901
8099
|
...widgets.values()
|
|
@@ -7906,12 +8104,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7906
8104
|
log11("widget unmounted", {
|
|
7907
8105
|
id,
|
|
7908
8106
|
tag: state?.props._tag
|
|
7909
|
-
}, {
|
|
7910
|
-
F: __dxlog_file17,
|
|
7911
|
-
L: 267,
|
|
7912
|
-
S: void 0,
|
|
7913
|
-
C: (f, a) => f(...a)
|
|
7914
|
-
});
|
|
8107
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7915
8108
|
widgets.delete(id);
|
|
7916
8109
|
setWidgets?.([
|
|
7917
8110
|
...widgets.values()
|
|
@@ -7920,7 +8113,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7920
8113
|
};
|
|
7921
8114
|
return notifier;
|
|
7922
8115
|
};
|
|
7923
|
-
var keyHandlers =
|
|
8116
|
+
var keyHandlers = keymap14.of([
|
|
7924
8117
|
{
|
|
7925
8118
|
key: "Mod-ArrowUp",
|
|
7926
8119
|
run: (view) => {
|
|
@@ -7941,7 +8134,7 @@ var keyHandlers = keymap13.of([
|
|
|
7941
8134
|
}
|
|
7942
8135
|
]);
|
|
7943
8136
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7944
|
-
return
|
|
8137
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7945
8138
|
update2.transactions.forEach((transaction) => {
|
|
7946
8139
|
for (const effect of transaction.effects) {
|
|
7947
8140
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7969,7 +8162,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7969
8162
|
anchor: line.from,
|
|
7970
8163
|
head: line.from
|
|
7971
8164
|
},
|
|
7972
|
-
effects:
|
|
8165
|
+
effects: crawlerLineEffect.of({
|
|
7973
8166
|
line: line.number - 1,
|
|
7974
8167
|
offset: -16
|
|
7975
8168
|
})
|
|
@@ -8002,7 +8195,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8002
8195
|
anchor: line.to,
|
|
8003
8196
|
head: line.to
|
|
8004
8197
|
},
|
|
8005
|
-
effects:
|
|
8198
|
+
effects: crawlerLineEffect.of({
|
|
8006
8199
|
line: line.number - 1,
|
|
8007
8200
|
offset: -16
|
|
8008
8201
|
})
|
|
@@ -8014,7 +8207,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8014
8207
|
anchor: line.to,
|
|
8015
8208
|
head: line.to
|
|
8016
8209
|
},
|
|
8017
|
-
effects:
|
|
8210
|
+
effects: crawlerLineEffect.of({
|
|
8018
8211
|
line: line.number - 1,
|
|
8019
8212
|
position: "end"
|
|
8020
8213
|
})
|
|
@@ -8026,7 +8219,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
8026
8219
|
});
|
|
8027
8220
|
});
|
|
8028
8221
|
};
|
|
8029
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8222
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
8030
8223
|
update(update2) {
|
|
8031
8224
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
8032
8225
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -8071,7 +8264,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8071
8264
|
}
|
|
8072
8265
|
return {
|
|
8073
8266
|
from: 0,
|
|
8074
|
-
decorations:
|
|
8267
|
+
decorations: Decoration18.none
|
|
8075
8268
|
};
|
|
8076
8269
|
}
|
|
8077
8270
|
}
|
|
@@ -8082,12 +8275,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8082
8275
|
log11("document reset", {
|
|
8083
8276
|
from,
|
|
8084
8277
|
to: state.doc.length
|
|
8085
|
-
}, {
|
|
8086
|
-
F: __dxlog_file17,
|
|
8087
|
-
L: 429,
|
|
8088
|
-
S: void 0,
|
|
8089
|
-
C: (f, a) => f(...a)
|
|
8090
|
-
});
|
|
8278
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
8091
8279
|
return buildDecorations4(state, {
|
|
8092
8280
|
from: 0,
|
|
8093
8281
|
to: state.doc.length
|
|
@@ -8116,8 +8304,8 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.def
|
|
|
8116
8304
|
};
|
|
8117
8305
|
},
|
|
8118
8306
|
provide: (field) => [
|
|
8119
|
-
|
|
8120
|
-
|
|
8307
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8308
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
8121
8309
|
]
|
|
8122
8310
|
});
|
|
8123
8311
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -8128,7 +8316,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8128
8316
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
8129
8317
|
return {
|
|
8130
8318
|
from: range.from,
|
|
8131
|
-
decorations:
|
|
8319
|
+
decorations: Decoration18.none
|
|
8132
8320
|
};
|
|
8133
8321
|
}
|
|
8134
8322
|
let last = range.from;
|
|
@@ -8164,7 +8352,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8164
8352
|
};
|
|
8165
8353
|
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
8166
8354
|
if (widget) {
|
|
8167
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8355
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
8168
8356
|
widget,
|
|
8169
8357
|
block,
|
|
8170
8358
|
atomic: true,
|
|
@@ -8176,12 +8364,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8176
8364
|
}
|
|
8177
8365
|
}
|
|
8178
8366
|
} catch (err) {
|
|
8179
|
-
log11.catch(err, void 0, {
|
|
8180
|
-
F: __dxlog_file17,
|
|
8181
|
-
L: 538,
|
|
8182
|
-
S: void 0,
|
|
8183
|
-
C: (f, a) => f(...a)
|
|
8184
|
-
});
|
|
8367
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
8185
8368
|
}
|
|
8186
8369
|
return false;
|
|
8187
8370
|
}
|
|
@@ -8228,7 +8411,7 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
8228
8411
|
};
|
|
8229
8412
|
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8230
8413
|
if (widget) {
|
|
8231
|
-
builder.add(absoluteFrom, range.to,
|
|
8414
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8232
8415
|
widget,
|
|
8233
8416
|
block: def.block,
|
|
8234
8417
|
atomic: true,
|
|
@@ -8260,15 +8443,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8260
8443
|
#view;
|
|
8261
8444
|
constructor(id, Component, props, notifier, streaming) {
|
|
8262
8445
|
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8263
|
-
invariant7(id, void 0, {
|
|
8264
|
-
F: __dxlog_file17,
|
|
8265
|
-
L: 641,
|
|
8266
|
-
S: this,
|
|
8267
|
-
A: [
|
|
8268
|
-
"id",
|
|
8269
|
-
""
|
|
8270
|
-
]
|
|
8271
|
-
});
|
|
8446
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
8272
8447
|
}
|
|
8273
8448
|
get root() {
|
|
8274
8449
|
return this.#root;
|
|
@@ -8284,9 +8459,7 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8284
8459
|
}
|
|
8285
8460
|
toDOM(view) {
|
|
8286
8461
|
this.#view = view;
|
|
8287
|
-
this.#root = Domino4.of("div").classNames("min-h-[24px]").
|
|
8288
|
-
[XML_WIDGET_DATA_ATTR]: ""
|
|
8289
|
-
}).root;
|
|
8462
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8290
8463
|
const props = Object.assign({}, this.props, {
|
|
8291
8464
|
view
|
|
8292
8465
|
});
|
|
@@ -8317,71 +8490,10 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
8317
8490
|
this.#view = void 0;
|
|
8318
8491
|
}
|
|
8319
8492
|
};
|
|
8320
|
-
|
|
8321
|
-
// src/extensions/typewriter.ts
|
|
8322
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
8323
|
-
var defaultItems = [
|
|
8324
|
-
"hello world!",
|
|
8325
|
-
"this is a test.",
|
|
8326
|
-
"this is [DXOS](https://dxos.org)"
|
|
8327
|
-
];
|
|
8328
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
8329
|
-
let t;
|
|
8330
|
-
let idx = 0;
|
|
8331
|
-
return [
|
|
8332
|
-
keymap14.of([
|
|
8333
|
-
{
|
|
8334
|
-
// Reset.
|
|
8335
|
-
key: "alt-meta-'",
|
|
8336
|
-
run: () => {
|
|
8337
|
-
clearTimeout(t);
|
|
8338
|
-
idx = 0;
|
|
8339
|
-
return true;
|
|
8340
|
-
}
|
|
8341
|
-
},
|
|
8342
|
-
{
|
|
8343
|
-
// Next prompt.
|
|
8344
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
8345
|
-
key: "Shift-Meta-'",
|
|
8346
|
-
run: (view) => {
|
|
8347
|
-
clearTimeout(t);
|
|
8348
|
-
const text = items[idx++];
|
|
8349
|
-
if (idx === items?.length) {
|
|
8350
|
-
idx = 0;
|
|
8351
|
-
}
|
|
8352
|
-
let i = 0;
|
|
8353
|
-
const insert = (d = 0) => {
|
|
8354
|
-
t = setTimeout(() => {
|
|
8355
|
-
const pos = view.state.selection.main.head;
|
|
8356
|
-
view.dispatch({
|
|
8357
|
-
changes: {
|
|
8358
|
-
from: pos,
|
|
8359
|
-
insert: text[i++]
|
|
8360
|
-
},
|
|
8361
|
-
selection: {
|
|
8362
|
-
anchor: pos + 1
|
|
8363
|
-
}
|
|
8364
|
-
});
|
|
8365
|
-
if (i < text.length) {
|
|
8366
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
8367
|
-
}
|
|
8368
|
-
}, d);
|
|
8369
|
-
};
|
|
8370
|
-
insert();
|
|
8371
|
-
return true;
|
|
8372
|
-
}
|
|
8373
|
-
}
|
|
8374
|
-
])
|
|
8375
|
-
];
|
|
8376
|
-
};
|
|
8377
8493
|
export {
|
|
8378
8494
|
Cursor,
|
|
8379
|
-
EditorInputMode,
|
|
8380
|
-
EditorInputModes,
|
|
8381
8495
|
EditorState4 as EditorState,
|
|
8382
|
-
|
|
8383
|
-
EditorViewMode,
|
|
8384
|
-
EditorViewModes,
|
|
8496
|
+
EditorView33 as EditorView,
|
|
8385
8497
|
Inline,
|
|
8386
8498
|
InputModeExtensions,
|
|
8387
8499
|
List,
|
|
@@ -8390,7 +8502,6 @@ export {
|
|
|
8390
8502
|
SpaceAwarenessProvider,
|
|
8391
8503
|
TextKind,
|
|
8392
8504
|
Tree,
|
|
8393
|
-
XML_WIDGET_DATA_ATTR,
|
|
8394
8505
|
addBlockquote,
|
|
8395
8506
|
addBookmark,
|
|
8396
8507
|
addCodeblock,
|
|
@@ -8415,6 +8526,9 @@ export {
|
|
|
8415
8526
|
commentsState,
|
|
8416
8527
|
compactSlots,
|
|
8417
8528
|
convertTreeToJson,
|
|
8529
|
+
crawler,
|
|
8530
|
+
crawlerActiveEffect,
|
|
8531
|
+
crawlerLineEffect,
|
|
8418
8532
|
createBasicExtensions,
|
|
8419
8533
|
createComment,
|
|
8420
8534
|
createCrawler,
|
|
@@ -8478,6 +8592,7 @@ export {
|
|
|
8478
8592
|
markdownTagsExtensions,
|
|
8479
8593
|
matchCompletion,
|
|
8480
8594
|
mention,
|
|
8595
|
+
mobileSlots,
|
|
8481
8596
|
modalStateEffect,
|
|
8482
8597
|
modalStateField,
|
|
8483
8598
|
moveItemDown,
|
|
@@ -8501,8 +8616,6 @@ export {
|
|
|
8501
8616
|
scrollThreadIntoView,
|
|
8502
8617
|
scrollToLine,
|
|
8503
8618
|
scroller,
|
|
8504
|
-
scrollerCrawlEffect,
|
|
8505
|
-
scrollerLineEffect,
|
|
8506
8619
|
selectionState,
|
|
8507
8620
|
setBlockquote,
|
|
8508
8621
|
setComments,
|
|
@@ -8510,6 +8623,7 @@ export {
|
|
|
8510
8623
|
setSelection,
|
|
8511
8624
|
setStyle,
|
|
8512
8625
|
singleValueFacet,
|
|
8626
|
+
snippets2 as snippets,
|
|
8513
8627
|
staticCompletion,
|
|
8514
8628
|
submit,
|
|
8515
8629
|
tabbable,
|
|
@@ -8529,10 +8643,12 @@ export {
|
|
|
8529
8643
|
treeFacet,
|
|
8530
8644
|
typeahead,
|
|
8531
8645
|
typewriter,
|
|
8532
|
-
|
|
8533
|
-
|
|
8646
|
+
typewriterBypass,
|
|
8647
|
+
typewriterDrainingEffect,
|
|
8534
8648
|
wrapWithCatch,
|
|
8649
|
+
xmlBlockDecoration,
|
|
8535
8650
|
xmlElementLength,
|
|
8651
|
+
xmlFormatting,
|
|
8536
8652
|
xmlTagContextEffect,
|
|
8537
8653
|
xmlTagResetEffect,
|
|
8538
8654
|
xmlTagUpdateEffect,
|