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