@dxos/ui-editor 0.8.4-main.c351d160a8 → 0.8.4-main.cb12b3f963
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +1523 -750
- 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 +1522 -748
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +27 -6
- package/dist/lib/node-esm/types/index.mjs.map +4 -4
- package/dist/types/src/defaults.d.ts +4 -10
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/auto-scroll.d.ts +14 -2
- package/dist/types/src/extensions/auto-scroll.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +4 -3
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/focus.d.ts +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +3 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -1
- package/dist/types/src/extensions/preview/preview.d.ts +2 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/replacer.d.ts.map +1 -1
- package/dist/types/src/extensions/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scroller.d.ts +12 -10
- package/dist/types/src/extensions/scroller.d.ts.map +1 -1
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +4 -1
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +28 -8
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts +2 -2
- 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 +33 -17
- package/src/extensions/auto-scroll.ts +115 -9
- package/src/extensions/automerge/automerge.test.tsx +35 -9
- package/src/extensions/automerge/automerge.ts +2 -5
- package/src/extensions/comments.ts +0 -1
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +26 -8
- package/src/extensions/folding.ts +3 -20
- package/src/extensions/index.ts +2 -1
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +11 -9
- package/src/extensions/markdown/highlight.ts +4 -10
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +37 -4
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +0 -1
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +54 -7
- package/src/extensions/scroll-past-end.ts +32 -0
- package/src/extensions/scroller.ts +46 -23
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +179 -31
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/theme.ts +39 -25
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +0 -1
- 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/tags/streamer.d.ts +0 -12
- package/dist/types/src/extensions/tags/streamer.d.ts.map +0 -1
- package/dist/types/src/extensions/typewriter.d.ts +0 -10
- package/dist/types/src/extensions/typewriter.d.ts.map +0 -1
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
|
@@ -1,26 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EditorInputMode,
|
|
3
|
-
EditorInputModes,
|
|
4
|
-
EditorViewMode,
|
|
5
|
-
EditorViewModes
|
|
6
|
-
} from "./chunk-HL3YF6WC.mjs";
|
|
7
|
-
|
|
8
1
|
// src/index.ts
|
|
9
|
-
import { EditorState as
|
|
10
|
-
import { EditorView as
|
|
2
|
+
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
3
|
+
import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
|
|
11
4
|
import { tags as tags2 } from "@lezer/highlight";
|
|
12
5
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
13
6
|
|
|
14
7
|
// src/defaults.ts
|
|
15
8
|
import { mx } from "@dxos/ui-theme";
|
|
16
|
-
var
|
|
17
|
-
var
|
|
9
|
+
var editorClassNames = (role) => mx("dx-attention-surface p-0.5 data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
10
|
+
var documentSlots = {
|
|
11
|
+
content: {
|
|
12
|
+
/**
|
|
13
|
+
* CodeMirror content width.
|
|
14
|
+
* 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
|
|
15
|
+
* 50rem = 800px. Maximum content width for solo mode.
|
|
16
|
+
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
17
|
+
*/
|
|
18
|
+
className: mx(
|
|
19
|
+
// Inline-size container for widget sizing (children use `max-w-[100cqi]`).
|
|
20
|
+
// NOTE: Use inline-size, not full size containment — `container-type: size` on the
|
|
21
|
+
// editor content breaks CodeMirror's viewport measurement, leaving blank gaps during
|
|
22
|
+
// scroll until a click forces a re-measure.
|
|
23
|
+
"dx-inline-size-container",
|
|
24
|
+
// Wider margin for web (vs. mobile).
|
|
25
|
+
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
26
|
+
"mx-auto! w-full"
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var compactSlots = {
|
|
31
|
+
content: {
|
|
32
|
+
className: "mx-2!"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var mobileSlots = {
|
|
18
36
|
content: {
|
|
19
|
-
className:
|
|
37
|
+
className: "mx-2!"
|
|
20
38
|
}
|
|
21
39
|
};
|
|
22
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
23
|
-
var stackItemContentEditorClassNames = (role) => mx("dx-attention-surface p-0.5 dx-focus-ring-inset data-[toolbar=disabled]:pt-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
24
40
|
|
|
25
41
|
// src/extensions/annotations.ts
|
|
26
42
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
@@ -204,7 +220,7 @@ var singleValueFacet = (defaultValue) => Facet.define({
|
|
|
204
220
|
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
205
221
|
var defaultCursorConverter = {
|
|
206
222
|
toCursor: (position) => position.toString(),
|
|
207
|
-
fromCursor: (
|
|
223
|
+
fromCursor: (cursor) => parseInt(cursor)
|
|
208
224
|
};
|
|
209
225
|
var Cursor = class _Cursor {
|
|
210
226
|
static converter = singleValueFacet(defaultCursorConverter);
|
|
@@ -217,9 +233,9 @@ var Cursor = class _Cursor {
|
|
|
217
233
|
to
|
|
218
234
|
].join(":");
|
|
219
235
|
};
|
|
220
|
-
static getRangeFromCursor = (state,
|
|
236
|
+
static getRangeFromCursor = (state, cursor) => {
|
|
221
237
|
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
222
|
-
const parts =
|
|
238
|
+
const parts = cursor.split(":");
|
|
223
239
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
224
240
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
225
241
|
return from !== void 0 && to !== void 0 ? {
|
|
@@ -255,12 +271,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
255
271
|
} catch (err) {
|
|
256
272
|
log.catch(err, {
|
|
257
273
|
label
|
|
258
|
-
}, {
|
|
259
|
-
F: __dxlog_file,
|
|
260
|
-
L: 20,
|
|
261
|
-
S: void 0,
|
|
262
|
-
C: (f, a) => f(...a)
|
|
263
|
-
});
|
|
274
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
264
275
|
}
|
|
265
276
|
};
|
|
266
277
|
};
|
|
@@ -286,12 +297,7 @@ var logChanges = (trs) => {
|
|
|
286
297
|
if (changes.length) {
|
|
287
298
|
log("changes", {
|
|
288
299
|
changes
|
|
289
|
-
}, {
|
|
290
|
-
F: __dxlog_file,
|
|
291
|
-
L: 54,
|
|
292
|
-
S: void 0,
|
|
293
|
-
C: (f, a) => f(...a)
|
|
294
|
-
});
|
|
300
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
295
301
|
}
|
|
296
302
|
};
|
|
297
303
|
|
|
@@ -499,9 +505,11 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
499
505
|
};
|
|
500
506
|
|
|
501
507
|
// src/extensions/auto-scroll.ts
|
|
508
|
+
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
502
509
|
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
503
510
|
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
504
511
|
import { Domino } from "@dxos/ui";
|
|
512
|
+
import { getSize } from "@dxos/ui-theme";
|
|
505
513
|
|
|
506
514
|
// src/extensions/scroller.ts
|
|
507
515
|
import { StateEffect } from "@codemirror/state";
|
|
@@ -580,23 +588,19 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
580
588
|
}
|
|
581
589
|
}
|
|
582
590
|
} catch (err) {
|
|
583
|
-
log2.catch(err, void 0, {
|
|
584
|
-
F: __dxlog_file2,
|
|
585
|
-
L: 146,
|
|
586
|
-
S: void 0,
|
|
587
|
-
C: (f, a) => f(...a)
|
|
588
|
-
});
|
|
591
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
|
|
589
592
|
}
|
|
590
593
|
});
|
|
591
594
|
}),
|
|
592
595
|
// Styles.
|
|
593
596
|
EditorView4.theme({
|
|
594
|
-
".cm-content": {
|
|
595
|
-
paddingBottom: `${overScroll}px`
|
|
596
|
-
},
|
|
597
597
|
".cm-scroller": {
|
|
598
|
-
|
|
599
|
-
|
|
598
|
+
overflowY: "scroll",
|
|
599
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
600
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
601
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
602
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
603
|
+
overflowAnchor: "auto"
|
|
600
604
|
},
|
|
601
605
|
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
602
606
|
display: "none"
|
|
@@ -608,6 +612,16 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
608
612
|
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
609
613
|
background: "var(--color-scrollbar-thumb)"
|
|
610
614
|
},
|
|
615
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
616
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
617
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
618
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
619
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
620
|
+
".cm-content::after": {
|
|
621
|
+
content: '""',
|
|
622
|
+
display: "block",
|
|
623
|
+
height: `${overScroll}px`
|
|
624
|
+
},
|
|
611
625
|
".cm-scroll-button": {
|
|
612
626
|
position: "absolute",
|
|
613
627
|
bottom: "0.5rem",
|
|
@@ -616,22 +630,28 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
616
630
|
})
|
|
617
631
|
];
|
|
618
632
|
};
|
|
619
|
-
function createCrawler(view,
|
|
633
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
620
634
|
const el = view.scrollDOM;
|
|
621
635
|
let currentTop = 0;
|
|
636
|
+
let velocity = 0;
|
|
622
637
|
let rafId = null;
|
|
623
|
-
|
|
638
|
+
let lastTime = 0;
|
|
639
|
+
function frame(now) {
|
|
640
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
641
|
+
lastTime = now;
|
|
624
642
|
const targetTop = el.scrollHeight - el.clientHeight;
|
|
625
643
|
const delta = targetTop - currentTop;
|
|
626
|
-
|
|
627
|
-
if (absDelta < targetDelta) {
|
|
644
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
628
645
|
el.scrollTop = targetTop;
|
|
629
646
|
currentTop = targetTop;
|
|
647
|
+
velocity = 0;
|
|
630
648
|
rafId = null;
|
|
649
|
+
lastTime = 0;
|
|
631
650
|
return;
|
|
632
651
|
}
|
|
633
|
-
const
|
|
634
|
-
|
|
652
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
653
|
+
velocity += accel * dt;
|
|
654
|
+
currentTop += velocity * dt;
|
|
635
655
|
el.scrollTop = currentTop;
|
|
636
656
|
rafId = requestAnimationFrame(frame);
|
|
637
657
|
}
|
|
@@ -639,12 +659,15 @@ function createCrawler(view, k = 0.3, maxStep = 2, targetDelta = 0.5) {
|
|
|
639
659
|
scroll: () => {
|
|
640
660
|
if (rafId === null) {
|
|
641
661
|
currentTop = el.scrollTop;
|
|
662
|
+
lastTime = 0;
|
|
642
663
|
rafId = requestAnimationFrame(frame);
|
|
643
664
|
}
|
|
644
665
|
},
|
|
645
666
|
cancel: () => {
|
|
646
667
|
if (rafId !== null) {
|
|
647
668
|
cancelAnimationFrame(rafId);
|
|
669
|
+
velocity = 0;
|
|
670
|
+
lastTime = 0;
|
|
648
671
|
rafId = null;
|
|
649
672
|
}
|
|
650
673
|
}
|
|
@@ -652,26 +675,64 @@ function createCrawler(view, k = 0.3, maxStep = 2, targetDelta = 0.5) {
|
|
|
652
675
|
}
|
|
653
676
|
|
|
654
677
|
// src/extensions/auto-scroll.ts
|
|
655
|
-
var
|
|
678
|
+
var autoScrollEffect = StateEffect2.define();
|
|
679
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
656
680
|
let buttonContainer;
|
|
657
681
|
let isPinned = true;
|
|
682
|
+
let jumpPending = false;
|
|
683
|
+
let enabled = true;
|
|
684
|
+
let firstUpdate = true;
|
|
658
685
|
const setPinned = (pinned) => {
|
|
659
686
|
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
660
687
|
isPinned = pinned;
|
|
661
688
|
};
|
|
662
689
|
return [
|
|
663
|
-
// Update listener for
|
|
664
|
-
EditorView5.updateListener.of((
|
|
690
|
+
// Update listener for scrolling when content changes.
|
|
691
|
+
EditorView5.updateListener.of((update2) => {
|
|
692
|
+
const { view, heightChanged, state, startState } = update2;
|
|
693
|
+
for (const tr of update2.transactions) {
|
|
694
|
+
for (const effect of tr.effects) {
|
|
695
|
+
if (effect.is(autoScrollEffect)) {
|
|
696
|
+
enabled = effect.value;
|
|
697
|
+
if (enabled) {
|
|
698
|
+
setPinned(true);
|
|
699
|
+
view.dispatch({
|
|
700
|
+
effects: scrollerCrawlEffect.of(true)
|
|
701
|
+
});
|
|
702
|
+
} else {
|
|
703
|
+
view.dispatch({
|
|
704
|
+
effects: scrollerCrawlEffect.of(false)
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
if (!enabled) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
714
|
+
firstUpdate = false;
|
|
715
|
+
jumpPending = true;
|
|
716
|
+
requestAnimationFrame(() => {
|
|
717
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
718
|
+
jumpPending = false;
|
|
719
|
+
});
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
firstUpdate = false;
|
|
723
|
+
if (jumpPending) {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
665
726
|
if (heightChanged) {
|
|
666
727
|
if (isPinned) {
|
|
667
728
|
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
668
729
|
const delta = scrollHeight - scrollTop - clientHeight;
|
|
669
|
-
if (delta > 0
|
|
730
|
+
if (delta > 0) {
|
|
670
731
|
setPinned(true);
|
|
671
732
|
view.dispatch({
|
|
672
733
|
effects: scrollerCrawlEffect.of(true)
|
|
673
734
|
});
|
|
674
|
-
} else if (delta <
|
|
735
|
+
} else if (delta < -1) {
|
|
675
736
|
setPinned(false);
|
|
676
737
|
}
|
|
677
738
|
} else {
|
|
@@ -681,6 +742,43 @@ var autoScroll = (_ = {}) => {
|
|
|
681
742
|
}
|
|
682
743
|
}
|
|
683
744
|
}),
|
|
745
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
746
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
747
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
748
|
+
scrollOnResize ? ViewPlugin6.fromClass(class {
|
|
749
|
+
observer;
|
|
750
|
+
firstObservation = true;
|
|
751
|
+
destroyed = false;
|
|
752
|
+
constructor(view) {
|
|
753
|
+
const onResize = throttle(() => {
|
|
754
|
+
if (this.destroyed || !enabled) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
setPinned(true);
|
|
758
|
+
requestAnimationFrame(() => {
|
|
759
|
+
if (this.destroyed) {
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
763
|
+
view.dispatch({
|
|
764
|
+
effects: scrollerCrawlEffect.of(true)
|
|
765
|
+
});
|
|
766
|
+
});
|
|
767
|
+
}, 100);
|
|
768
|
+
this.observer = new ResizeObserver(() => {
|
|
769
|
+
if (this.firstObservation) {
|
|
770
|
+
this.firstObservation = false;
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
onResize();
|
|
774
|
+
});
|
|
775
|
+
this.observer.observe(view.scrollDOM);
|
|
776
|
+
}
|
|
777
|
+
destroy() {
|
|
778
|
+
this.destroyed = true;
|
|
779
|
+
this.observer.disconnect();
|
|
780
|
+
}
|
|
781
|
+
}) : [],
|
|
684
782
|
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
685
783
|
ViewPlugin6.fromClass(class {
|
|
686
784
|
cleanup;
|
|
@@ -706,12 +804,12 @@ var autoScroll = (_ = {}) => {
|
|
|
706
804
|
// Scroll button.
|
|
707
805
|
ViewPlugin6.fromClass(class {
|
|
708
806
|
constructor(view) {
|
|
709
|
-
const icon = Domino.of("dx-icon").attributes({
|
|
807
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
710
808
|
icon: "ph--arrow-down--regular"
|
|
711
809
|
});
|
|
712
810
|
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
713
811
|
"data-density": "fine"
|
|
714
|
-
}).
|
|
812
|
+
}).append(icon).on("click", () => {
|
|
715
813
|
setPinned(true);
|
|
716
814
|
view.dispatch({
|
|
717
815
|
effects: scrollerLineEffect.of({
|
|
@@ -721,7 +819,7 @@ var autoScroll = (_ = {}) => {
|
|
|
721
819
|
})
|
|
722
820
|
});
|
|
723
821
|
});
|
|
724
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").
|
|
822
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
725
823
|
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
726
824
|
}
|
|
727
825
|
})
|
|
@@ -756,35 +854,25 @@ var cursorConverter = (accessor) => ({
|
|
|
756
854
|
try {
|
|
757
855
|
return toCursor(accessor, pos, assoc);
|
|
758
856
|
} catch (err) {
|
|
759
|
-
log3.catch(err, void 0, {
|
|
760
|
-
F: __dxlog_file3,
|
|
761
|
-
L: 15,
|
|
762
|
-
S: void 0,
|
|
763
|
-
C: (f, a) => f(...a)
|
|
764
|
-
});
|
|
857
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 11, S: void 0 });
|
|
765
858
|
return "";
|
|
766
859
|
}
|
|
767
860
|
},
|
|
768
|
-
fromCursor: (
|
|
861
|
+
fromCursor: (cursor) => {
|
|
769
862
|
try {
|
|
770
|
-
return fromCursor(accessor,
|
|
863
|
+
return fromCursor(accessor, cursor);
|
|
771
864
|
} catch (err) {
|
|
772
|
-
log3.catch(err, void 0, {
|
|
773
|
-
F: __dxlog_file3,
|
|
774
|
-
L: 24,
|
|
775
|
-
S: void 0,
|
|
776
|
-
C: (f, a) => f(...a)
|
|
777
|
-
});
|
|
865
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 19, S: void 0 });
|
|
778
866
|
return 0;
|
|
779
867
|
}
|
|
780
868
|
}
|
|
781
869
|
});
|
|
782
870
|
|
|
783
871
|
// src/extensions/automerge/defs.ts
|
|
784
|
-
import { Annotation, StateEffect as
|
|
872
|
+
import { Annotation, StateEffect as StateEffect3 } from "@codemirror/state";
|
|
785
873
|
var getPath = (state, field) => state.field(field).path;
|
|
786
874
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
787
|
-
var updateHeadsEffect =
|
|
875
|
+
var updateHeadsEffect = StateEffect3.define({});
|
|
788
876
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
789
877
|
newHeads
|
|
790
878
|
});
|
|
@@ -959,12 +1047,7 @@ var Syncer = class {
|
|
|
959
1047
|
this._pending = false;
|
|
960
1048
|
}
|
|
961
1049
|
onEditorChange(view) {
|
|
962
|
-
log4("onEditorChange", void 0, {
|
|
963
|
-
F: __dxlog_file4,
|
|
964
|
-
L: 45,
|
|
965
|
-
S: this,
|
|
966
|
-
C: (f, a) => f(...a)
|
|
967
|
-
});
|
|
1050
|
+
log4("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 35, S: this });
|
|
968
1051
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
969
1052
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
970
1053
|
if (newHeads) {
|
|
@@ -975,12 +1058,7 @@ var Syncer = class {
|
|
|
975
1058
|
}
|
|
976
1059
|
}
|
|
977
1060
|
onAutomergeChange(view) {
|
|
978
|
-
log4("onAutomergeChange", void 0, {
|
|
979
|
-
F: __dxlog_file4,
|
|
980
|
-
L: 60,
|
|
981
|
-
S: this,
|
|
982
|
-
C: (f, a) => f(...a)
|
|
983
|
-
});
|
|
1061
|
+
log4("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 47, S: this });
|
|
984
1062
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
985
1063
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
986
1064
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1042,14 +1120,16 @@ var automerge = (accessor) => {
|
|
|
1042
1120
|
const value = DocAccessor.getValue(accessor);
|
|
1043
1121
|
const current = this._view.state.doc.toString();
|
|
1044
1122
|
if (value !== current) {
|
|
1045
|
-
console.warn("ENABLING INITIAL SYNC -- THIS MAY BE A REGRESSION");
|
|
1046
1123
|
this._view.dispatch({
|
|
1047
1124
|
changes: {
|
|
1048
1125
|
from: 0,
|
|
1049
1126
|
to: this._view.state.doc.length,
|
|
1050
1127
|
insert: value
|
|
1051
1128
|
},
|
|
1052
|
-
annotations:
|
|
1129
|
+
annotations: [
|
|
1130
|
+
initialSync,
|
|
1131
|
+
reconcileAnnotation.of(true)
|
|
1132
|
+
]
|
|
1053
1133
|
});
|
|
1054
1134
|
}
|
|
1055
1135
|
});
|
|
@@ -1101,10 +1181,7 @@ var awareness = (provider = dummyProvider) => {
|
|
|
1101
1181
|
];
|
|
1102
1182
|
};
|
|
1103
1183
|
var RemoteSelectionsDecorator = class {
|
|
1104
|
-
_ctx = new Context(void 0, {
|
|
1105
|
-
F: __dxlog_file5,
|
|
1106
|
-
L: 80
|
|
1107
|
-
});
|
|
1184
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
|
|
1108
1185
|
_cursorConverter;
|
|
1109
1186
|
_provider;
|
|
1110
1187
|
_lastAnchor;
|
|
@@ -1335,10 +1412,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1335
1412
|
this._info = info;
|
|
1336
1413
|
}
|
|
1337
1414
|
open() {
|
|
1338
|
-
this._ctx = new Context2(void 0, {
|
|
1339
|
-
F: __dxlog_file6,
|
|
1340
|
-
L: 57
|
|
1341
|
-
});
|
|
1415
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
|
|
1342
1416
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1343
1417
|
if (this._localState) {
|
|
1344
1418
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1365,12 +1439,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1365
1439
|
}).catch((err) => {
|
|
1366
1440
|
log5.debug("failed to query awareness", {
|
|
1367
1441
|
err
|
|
1368
|
-
}, {
|
|
1369
|
-
F: __dxlog_file6,
|
|
1370
|
-
L: 91,
|
|
1371
|
-
S: this,
|
|
1372
|
-
C: (f, a) => f(...a)
|
|
1373
|
-
});
|
|
1442
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
|
|
1374
1443
|
});
|
|
1375
1444
|
}
|
|
1376
1445
|
close() {
|
|
@@ -1382,15 +1451,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1382
1451
|
return Array.from(this._remoteStates.values());
|
|
1383
1452
|
}
|
|
1384
1453
|
update(position) {
|
|
1385
|
-
invariant(this._postTask, void 0, {
|
|
1386
|
-
F: __dxlog_file6,
|
|
1387
|
-
L: 106,
|
|
1388
|
-
S: this,
|
|
1389
|
-
A: [
|
|
1390
|
-
"this._postTask",
|
|
1391
|
-
""
|
|
1392
|
-
]
|
|
1393
|
-
});
|
|
1454
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1394
1455
|
this._localState = {
|
|
1395
1456
|
peerId: this._peerId,
|
|
1396
1457
|
position,
|
|
@@ -1399,27 +1460,11 @@ var SpaceAwarenessProvider = class {
|
|
|
1399
1460
|
this._postTask.schedule();
|
|
1400
1461
|
}
|
|
1401
1462
|
_handleQueryMessage() {
|
|
1402
|
-
invariant(this._postTask, void 0, {
|
|
1403
|
-
F: __dxlog_file6,
|
|
1404
|
-
L: 117,
|
|
1405
|
-
S: this,
|
|
1406
|
-
A: [
|
|
1407
|
-
"this._postTask",
|
|
1408
|
-
""
|
|
1409
|
-
]
|
|
1410
|
-
});
|
|
1463
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1411
1464
|
this._postTask.schedule();
|
|
1412
1465
|
}
|
|
1413
1466
|
_handlePostMessage(message) {
|
|
1414
|
-
invariant(message.kind === "post", void 0, {
|
|
1415
|
-
F: __dxlog_file6,
|
|
1416
|
-
L: 122,
|
|
1417
|
-
S: this,
|
|
1418
|
-
A: [
|
|
1419
|
-
"message.kind === 'post'",
|
|
1420
|
-
""
|
|
1421
|
-
]
|
|
1422
|
-
});
|
|
1467
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1423
1468
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1424
1469
|
this.remoteStateChange.emit();
|
|
1425
1470
|
}
|
|
@@ -1548,15 +1593,7 @@ var Blaster = class {
|
|
|
1548
1593
|
return this._node;
|
|
1549
1594
|
}
|
|
1550
1595
|
initialize() {
|
|
1551
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1552
|
-
F: __dxlog_file7,
|
|
1553
|
-
L: 142,
|
|
1554
|
-
S: this,
|
|
1555
|
-
A: [
|
|
1556
|
-
"!this._canvas && !this._ctx",
|
|
1557
|
-
""
|
|
1558
|
-
]
|
|
1559
|
-
});
|
|
1596
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1560
1597
|
this._canvas = document.createElement("canvas");
|
|
1561
1598
|
this._canvas.id = "code-blast-canvas";
|
|
1562
1599
|
this._canvas.style.position = "absolute";
|
|
@@ -1585,15 +1622,7 @@ var Blaster = class {
|
|
|
1585
1622
|
}
|
|
1586
1623
|
}
|
|
1587
1624
|
start() {
|
|
1588
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1589
|
-
F: __dxlog_file7,
|
|
1590
|
-
L: 181,
|
|
1591
|
-
S: this,
|
|
1592
|
-
A: [
|
|
1593
|
-
"this._canvas && this._ctx",
|
|
1594
|
-
""
|
|
1595
|
-
]
|
|
1596
|
-
});
|
|
1625
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1597
1626
|
this._running = true;
|
|
1598
1627
|
this.loop();
|
|
1599
1628
|
}
|
|
@@ -1828,13 +1857,13 @@ var blocks = () => [
|
|
|
1828
1857
|
];
|
|
1829
1858
|
|
|
1830
1859
|
// src/extensions/bookmarks.ts
|
|
1831
|
-
import { Prec as Prec3, StateEffect as
|
|
1860
|
+
import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
|
|
1832
1861
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1833
1862
|
import { log as log6 } from "@dxos/log";
|
|
1834
1863
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1835
|
-
var addBookmark =
|
|
1836
|
-
var removeBookmark =
|
|
1837
|
-
var clearBookmarks =
|
|
1864
|
+
var addBookmark = StateEffect4.define();
|
|
1865
|
+
var removeBookmark = StateEffect4.define();
|
|
1866
|
+
var clearBookmarks = StateEffect4.define();
|
|
1838
1867
|
var bookmarks = () => {
|
|
1839
1868
|
return [
|
|
1840
1869
|
bookmarksField,
|
|
@@ -1843,12 +1872,7 @@ var bookmarks = () => {
|
|
|
1843
1872
|
key: "Mod-ArrowUp",
|
|
1844
1873
|
run: (view) => {
|
|
1845
1874
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1846
|
-
log6("up", bookmarks2, {
|
|
1847
|
-
F: __dxlog_file8,
|
|
1848
|
-
L: 29,
|
|
1849
|
-
S: void 0,
|
|
1850
|
-
C: (f, a) => f(...a)
|
|
1851
|
-
});
|
|
1875
|
+
log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
|
|
1852
1876
|
return true;
|
|
1853
1877
|
}
|
|
1854
1878
|
},
|
|
@@ -1856,12 +1880,7 @@ var bookmarks = () => {
|
|
|
1856
1880
|
key: "Mod-ArrowDown",
|
|
1857
1881
|
run: (view) => {
|
|
1858
1882
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1859
|
-
log6("down", bookmarks2, {
|
|
1860
|
-
F: __dxlog_file8,
|
|
1861
|
-
L: 37,
|
|
1862
|
-
S: void 0,
|
|
1863
|
-
C: (f, a) => f(...a)
|
|
1864
|
-
});
|
|
1883
|
+
log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
|
|
1865
1884
|
return true;
|
|
1866
1885
|
}
|
|
1867
1886
|
}
|
|
@@ -1898,7 +1917,7 @@ var bookmarksField = StateField2.define({
|
|
|
1898
1917
|
|
|
1899
1918
|
// src/extensions/comments.ts
|
|
1900
1919
|
import { invertedEffects } from "@codemirror/commands";
|
|
1901
|
-
import { StateEffect as
|
|
1920
|
+
import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
|
|
1902
1921
|
import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1903
1922
|
import sortBy from "lodash.sortby";
|
|
1904
1923
|
import { debounce as debounce2 } from "@dxos/async";
|
|
@@ -1926,28 +1945,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1926
1945
|
};
|
|
1927
1946
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1928
1947
|
getState: (id) => {
|
|
1929
|
-
invariant3(id, void 0, {
|
|
1930
|
-
F: __dxlog_file9,
|
|
1931
|
-
L: 47,
|
|
1932
|
-
S: void 0,
|
|
1933
|
-
A: [
|
|
1934
|
-
"id",
|
|
1935
|
-
""
|
|
1936
|
-
]
|
|
1937
|
-
});
|
|
1948
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
|
|
1938
1949
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1939
1950
|
return state ? JSON.parse(state) : void 0;
|
|
1940
1951
|
},
|
|
1941
1952
|
setState: (id, state) => {
|
|
1942
|
-
invariant3(id, void 0, {
|
|
1943
|
-
F: __dxlog_file9,
|
|
1944
|
-
L: 53,
|
|
1945
|
-
S: void 0,
|
|
1946
|
-
A: [
|
|
1947
|
-
"id",
|
|
1948
|
-
""
|
|
1949
|
-
]
|
|
1950
|
-
});
|
|
1953
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
|
|
1951
1954
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1952
1955
|
}
|
|
1953
1956
|
});
|
|
@@ -2000,9 +2003,9 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2000
2003
|
|
|
2001
2004
|
// src/extensions/comments.ts
|
|
2002
2005
|
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
2003
|
-
var setComments =
|
|
2004
|
-
var setSelection =
|
|
2005
|
-
var setCommentState =
|
|
2006
|
+
var setComments = StateEffect5.define();
|
|
2007
|
+
var setSelection = StateEffect5.define();
|
|
2008
|
+
var setCommentState = StateEffect5.define();
|
|
2006
2009
|
var commentsState = StateField3.define({
|
|
2007
2010
|
create: (state) => ({
|
|
2008
2011
|
id: state.facet(documentId),
|
|
@@ -2069,12 +2072,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2069
2072
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2070
2073
|
const range = comment.range;
|
|
2071
2074
|
if (!range) {
|
|
2072
|
-
log7.warn("Invalid range:", range, {
|
|
2073
|
-
F: __dxlog_file10,
|
|
2074
|
-
L: 140,
|
|
2075
|
-
S: void 0,
|
|
2076
|
-
C: (f, a) => f(...a)
|
|
2077
|
-
});
|
|
2075
|
+
log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
|
|
2078
2076
|
return void 0;
|
|
2079
2077
|
} else if (range.from === range.to) {
|
|
2080
2078
|
return void 0;
|
|
@@ -2084,7 +2082,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2084
2082
|
}).filter(isNonNullable);
|
|
2085
2083
|
return Decoration7.set(decorations2);
|
|
2086
2084
|
});
|
|
2087
|
-
var commentClickedEffect =
|
|
2085
|
+
var commentClickedEffect = StateEffect5.define();
|
|
2088
2086
|
var handleCommentClick = EditorView11.domEventHandlers({
|
|
2089
2087
|
click: (event, view) => {
|
|
2090
2088
|
let target = event.target;
|
|
@@ -2187,10 +2185,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2187
2185
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2188
2186
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2189
2187
|
if (!exists) {
|
|
2190
|
-
const
|
|
2188
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2191
2189
|
onUpdate({
|
|
2192
2190
|
id: comment.id,
|
|
2193
|
-
cursor
|
|
2191
|
+
cursor
|
|
2194
2192
|
});
|
|
2195
2193
|
}
|
|
2196
2194
|
}
|
|
@@ -2202,7 +2200,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2202
2200
|
from: changes.mapPos(comment.from, 1),
|
|
2203
2201
|
to: changes.mapPos(comment.to, 1)
|
|
2204
2202
|
});
|
|
2205
|
-
var restoreCommentEffect =
|
|
2203
|
+
var restoreCommentEffect = StateEffect5.define({
|
|
2206
2204
|
map: mapTrackedComment
|
|
2207
2205
|
});
|
|
2208
2206
|
var createComment = (view) => {
|
|
@@ -2219,13 +2217,13 @@ var createComment = (view) => {
|
|
|
2219
2217
|
}
|
|
2220
2218
|
});
|
|
2221
2219
|
}
|
|
2222
|
-
const
|
|
2220
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2223
2221
|
from,
|
|
2224
2222
|
to
|
|
2225
2223
|
});
|
|
2226
|
-
if (
|
|
2224
|
+
if (cursor) {
|
|
2227
2225
|
options.onCreate?.({
|
|
2228
|
-
cursor
|
|
2226
|
+
cursor,
|
|
2229
2227
|
from,
|
|
2230
2228
|
location: view.coordsAtPos(from)
|
|
2231
2229
|
});
|
|
@@ -2466,7 +2464,7 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2466
2464
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2467
2465
|
import { searchKeymap } from "@codemirror/search";
|
|
2468
2466
|
import { EditorState } from "@codemirror/state";
|
|
2469
|
-
import { EditorView as
|
|
2467
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2470
2468
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2471
2469
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2472
2470
|
import { generateName } from "@dxos/display-name";
|
|
@@ -2478,28 +2476,28 @@ import { EditorView as EditorView13 } from "@codemirror/view";
|
|
|
2478
2476
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2479
2477
|
var headings = {
|
|
2480
2478
|
1: {
|
|
2481
|
-
className: "text-
|
|
2482
|
-
fontSize: "var(--text-
|
|
2479
|
+
className: "text-3xl",
|
|
2480
|
+
fontSize: "var(--text-3xl)",
|
|
2483
2481
|
lineHeight: "var(--text-4xl--line-height)"
|
|
2484
2482
|
},
|
|
2485
2483
|
2: {
|
|
2486
|
-
className: "text-
|
|
2487
|
-
fontSize: "var(--text-
|
|
2484
|
+
className: "text-2xl",
|
|
2485
|
+
fontSize: "var(--text-2xl)",
|
|
2488
2486
|
lineHeight: "var(--text-3xl--line-height)"
|
|
2489
2487
|
},
|
|
2490
2488
|
3: {
|
|
2491
|
-
className: "text-
|
|
2492
|
-
fontSize: "var(--text-
|
|
2489
|
+
className: "text-xl",
|
|
2490
|
+
fontSize: "var(--text-xl)",
|
|
2493
2491
|
lineHeight: "var(--text-2xl--line-height)"
|
|
2494
2492
|
},
|
|
2495
2493
|
4: {
|
|
2496
|
-
className: "text-
|
|
2497
|
-
fontSize: "var(--text-
|
|
2494
|
+
className: "text-lg",
|
|
2495
|
+
fontSize: "var(--text-lg)",
|
|
2498
2496
|
lineHeight: "var(--text-xl--line-height)"
|
|
2499
2497
|
},
|
|
2500
2498
|
5: {
|
|
2501
|
-
className: "text-
|
|
2502
|
-
fontSize: "var(--text-
|
|
2499
|
+
className: "text-base",
|
|
2500
|
+
fontSize: "var(--text-base)",
|
|
2503
2501
|
lineHeight: "var(--text-lg--line-height)"
|
|
2504
2502
|
},
|
|
2505
2503
|
6: {
|
|
@@ -2508,20 +2506,20 @@ var headings = {
|
|
|
2508
2506
|
lineHeight: "var(--text-base--line-height)"
|
|
2509
2507
|
}
|
|
2510
2508
|
};
|
|
2509
|
+
var fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
|
|
2510
|
+
var fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
|
|
2511
2511
|
var markdownTheme = {
|
|
2512
|
-
code: "font-mono
|
|
2513
|
-
codeMark: "font-mono
|
|
2514
|
-
mark: "
|
|
2512
|
+
code: "font-mono! cm-code-inline",
|
|
2513
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2514
|
+
mark: "font-mono!",
|
|
2515
2515
|
heading: (level) => ({
|
|
2516
|
-
className: mx3(headings[level].className, "font-light text-cm-heading"),
|
|
2516
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2517
2517
|
color: "var(--color-cm-heading) !important",
|
|
2518
2518
|
lineHeight: headings[level].lineHeight,
|
|
2519
2519
|
fontSize: headings[level].fontSize,
|
|
2520
2520
|
fontWeight: "100 !important"
|
|
2521
2521
|
})
|
|
2522
2522
|
};
|
|
2523
|
-
var fontBody = "Inter Variable, ui-sans-serif, system-ui, sans-serif";
|
|
2524
|
-
var fontMono = "JetBrains Mono Variable, ui-monospace, Cascadia Code, Source Code Pro, monospace";
|
|
2525
2523
|
var baseTheme = EditorView13.baseTheme({
|
|
2526
2524
|
/**
|
|
2527
2525
|
* Outer frame.
|
|
@@ -2534,12 +2532,21 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2534
2532
|
* Scroller
|
|
2535
2533
|
*/
|
|
2536
2534
|
".cm-scroller": {
|
|
2537
|
-
|
|
2535
|
+
// Browser scroll-anchoring: see comment in `scroller.ts`. `auto` lets the browser pin a
|
|
2536
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2537
|
+
// open/close) don't jump the user's view.
|
|
2538
|
+
overflowAnchor: "auto"
|
|
2538
2539
|
},
|
|
2539
2540
|
".cm-scroller::-webkit-scrollbar": {
|
|
2540
|
-
width: "8px"
|
|
2541
|
+
width: "var(--scrollbar-size,8px)",
|
|
2542
|
+
height: "var(--scrollbar-size,8px)"
|
|
2543
|
+
},
|
|
2544
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2545
|
+
background: "transparent"
|
|
2546
|
+
},
|
|
2547
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2548
|
+
background: "transparent"
|
|
2541
2549
|
},
|
|
2542
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2543
2550
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2544
2551
|
background: "transparent",
|
|
2545
2552
|
transition: "background 0.15s"
|
|
@@ -2553,7 +2560,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2553
2560
|
*/
|
|
2554
2561
|
".cm-content": {
|
|
2555
2562
|
padding: "unset",
|
|
2556
|
-
lineHeight: "24px",
|
|
2557
2563
|
color: "unset"
|
|
2558
2564
|
},
|
|
2559
2565
|
/**
|
|
@@ -2584,9 +2590,16 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2584
2590
|
* Line.
|
|
2585
2591
|
*/
|
|
2586
2592
|
".cm-line": {
|
|
2587
|
-
lineHeight:
|
|
2593
|
+
lineHeight: 1.5,
|
|
2588
2594
|
paddingInline: 0
|
|
2589
2595
|
},
|
|
2596
|
+
/**
|
|
2597
|
+
* Force all inline children to inherit line-height to prevent monospace font metrics
|
|
2598
|
+
* (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
|
|
2599
|
+
*/
|
|
2600
|
+
".cm-line *": {
|
|
2601
|
+
lineHeight: "inherit"
|
|
2602
|
+
},
|
|
2590
2603
|
".cm-activeLine": {
|
|
2591
2604
|
background: "var(--color-cm-active-line)"
|
|
2592
2605
|
},
|
|
@@ -2764,10 +2777,9 @@ var editorGutter = EditorView13.theme({
|
|
|
2764
2777
|
}
|
|
2765
2778
|
});
|
|
2766
2779
|
var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
2767
|
-
//
|
|
2780
|
+
// Main content.
|
|
2768
2781
|
".cm-scroller": {
|
|
2769
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2770
|
-
fontSize: "16px"
|
|
2782
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2771
2783
|
},
|
|
2772
2784
|
// Maintain defaults for UI components.
|
|
2773
2785
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2777,9 +2789,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2777
2789
|
});
|
|
2778
2790
|
|
|
2779
2791
|
// src/extensions/focus.ts
|
|
2780
|
-
import { StateEffect as
|
|
2792
|
+
import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
|
|
2781
2793
|
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
2782
|
-
var focusEffect =
|
|
2794
|
+
var focusEffect = StateEffect6.define();
|
|
2783
2795
|
var focusField = StateField5.define({
|
|
2784
2796
|
create: () => false,
|
|
2785
2797
|
update: (value, tr) => {
|
|
@@ -2807,9 +2819,32 @@ var focus = [
|
|
|
2807
2819
|
})
|
|
2808
2820
|
];
|
|
2809
2821
|
|
|
2822
|
+
// src/extensions/scroll-past-end.ts
|
|
2823
|
+
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2824
|
+
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2825
|
+
height = 1e3;
|
|
2826
|
+
attrs = {
|
|
2827
|
+
style: "padding-bottom: 1000px"
|
|
2828
|
+
};
|
|
2829
|
+
update({ view }) {
|
|
2830
|
+
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2831
|
+
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2832
|
+
if (height >= 0 && height !== this.height) {
|
|
2833
|
+
this.height = height;
|
|
2834
|
+
this.attrs = {
|
|
2835
|
+
style: `padding-bottom: ${height}px`
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
});
|
|
2840
|
+
var scrollPastEnd = () => [
|
|
2841
|
+
scrollPastEndPlugin,
|
|
2842
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null)
|
|
2843
|
+
];
|
|
2844
|
+
|
|
2810
2845
|
// src/extensions/factories.ts
|
|
2811
2846
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2812
|
-
var tabbable =
|
|
2847
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2813
2848
|
tabindex: "0"
|
|
2814
2849
|
});
|
|
2815
2850
|
var filterChars = (chars) => {
|
|
@@ -2862,13 +2897,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2862
2897
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2863
2898
|
return [
|
|
2864
2899
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2865
|
-
|
|
2866
|
-
log8.catch(err, void 0, {
|
|
2867
|
-
F: __dxlog_file11,
|
|
2868
|
-
L: 131,
|
|
2869
|
-
S: void 0,
|
|
2870
|
-
C: (f, a) => f(...a)
|
|
2871
|
-
});
|
|
2900
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2901
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2872
2902
|
}),
|
|
2873
2903
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2874
2904
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2877,7 +2907,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2877
2907
|
props.drawSelection && drawSelection({
|
|
2878
2908
|
cursorBlinkRate: 1200
|
|
2879
2909
|
}),
|
|
2880
|
-
props.editable !== void 0 &&
|
|
2910
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2881
2911
|
props.focus && focus,
|
|
2882
2912
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2883
2913
|
props.history && history(),
|
|
@@ -2885,9 +2915,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2885
2915
|
lineNumbers(),
|
|
2886
2916
|
editorGutter
|
|
2887
2917
|
],
|
|
2888
|
-
props.lineWrapping &&
|
|
2918
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2889
2919
|
props.placeholder && placeholder2(props.placeholder),
|
|
2890
2920
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2921
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
2922
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
2923
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
2924
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
2925
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
2926
|
+
// depend on being able to populate the doc themselves.
|
|
2927
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2891
2928
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2892
2929
|
props.tabbable && tabbable,
|
|
2893
2930
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2930,24 +2967,29 @@ var defaultStyles = {
|
|
|
2930
2967
|
dark: vscodeDarkStyle,
|
|
2931
2968
|
light: vscodeLightStyle
|
|
2932
2969
|
};
|
|
2933
|
-
var createThemeExtensions = ({ monospace,
|
|
2970
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2934
2971
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2935
2972
|
return [
|
|
2936
2973
|
baseTheme,
|
|
2937
|
-
|
|
2974
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2938
2975
|
createFontTheme({
|
|
2939
2976
|
monospace
|
|
2940
2977
|
}),
|
|
2941
2978
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2942
|
-
slots.editor?.className &&
|
|
2979
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2943
2980
|
class: slots.editor.className
|
|
2944
2981
|
}),
|
|
2945
|
-
slots.content?.className &&
|
|
2982
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2946
2983
|
class: slots.content.className
|
|
2947
2984
|
}),
|
|
2948
|
-
slots.
|
|
2985
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2949
2986
|
constructor(view) {
|
|
2950
|
-
|
|
2987
|
+
if (slots.scroller?.className) {
|
|
2988
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
2989
|
+
}
|
|
2990
|
+
if (scrollbarThin) {
|
|
2991
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
2992
|
+
}
|
|
2951
2993
|
}
|
|
2952
2994
|
})
|
|
2953
2995
|
].filter(isTruthy2);
|
|
@@ -2976,7 +3018,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2976
3018
|
|
|
2977
3019
|
// src/extensions/folding.ts
|
|
2978
3020
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2979
|
-
import { EditorView as
|
|
3021
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2980
3022
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2981
3023
|
var folding = () => {
|
|
2982
3024
|
return [
|
|
@@ -2984,13 +3026,14 @@ var folding = () => {
|
|
|
2984
3026
|
placeholderDOM: () => Domino2.of("span").root
|
|
2985
3027
|
}),
|
|
2986
3028
|
foldGutter({
|
|
3029
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2987
3030
|
markerDOM: (open) => {
|
|
2988
|
-
return Domino2.of("div").classNames("flex h-full justify-center items-center").
|
|
3031
|
+
return Domino2.of("div").classNames("flex h-full justify-center items-center").append(Domino2.of("svg", Domino2.SVG).classNames(mx4("w-4 h-4 cursor-pointer", open && "rotate-90")).append(Domino2.of("use", Domino2.SVG).attributes({
|
|
2989
3032
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2990
3033
|
}))).root;
|
|
2991
3034
|
}
|
|
2992
3035
|
}),
|
|
2993
|
-
|
|
3036
|
+
EditorView17.theme({
|
|
2994
3037
|
".cm-foldGutter": {
|
|
2995
3038
|
opacity: 0.3,
|
|
2996
3039
|
transition: "opacity 0.3s",
|
|
@@ -3004,7 +3047,7 @@ var folding = () => {
|
|
|
3004
3047
|
};
|
|
3005
3048
|
|
|
3006
3049
|
// src/extensions/hashtag.ts
|
|
3007
|
-
import { Decoration as Decoration8, EditorView as
|
|
3050
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3008
3051
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
3009
3052
|
var TagWidget = class extends WidgetType4 {
|
|
3010
3053
|
_text;
|
|
@@ -3025,7 +3068,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3025
3068
|
})
|
|
3026
3069
|
});
|
|
3027
3070
|
var hashtag = () => [
|
|
3028
|
-
|
|
3071
|
+
ViewPlugin13.fromClass(class {
|
|
3029
3072
|
tags;
|
|
3030
3073
|
constructor(view) {
|
|
3031
3074
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3035,11 +3078,11 @@ var hashtag = () => [
|
|
|
3035
3078
|
}
|
|
3036
3079
|
}, {
|
|
3037
3080
|
decorations: (instance) => instance.tags,
|
|
3038
|
-
provide: (plugin) =>
|
|
3081
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
3039
3082
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3040
3083
|
})
|
|
3041
3084
|
}),
|
|
3042
|
-
|
|
3085
|
+
EditorView18.theme({
|
|
3043
3086
|
".cm-tag": {
|
|
3044
3087
|
borderRadius: "4px",
|
|
3045
3088
|
marginRight: "6px",
|
|
@@ -3094,18 +3137,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3094
3137
|
};
|
|
3095
3138
|
|
|
3096
3139
|
// src/extensions/listener.ts
|
|
3097
|
-
import { EditorView as
|
|
3140
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3098
3141
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3099
3142
|
var listener = ({ onFocus, onChange }) => {
|
|
3100
3143
|
return [
|
|
3101
|
-
onFocus &&
|
|
3144
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3102
3145
|
onFocus({
|
|
3103
3146
|
id: state.facet(documentId),
|
|
3104
3147
|
focusing
|
|
3105
3148
|
});
|
|
3106
3149
|
return null;
|
|
3107
3150
|
}),
|
|
3108
|
-
onChange &&
|
|
3151
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3109
3152
|
if (docChanged) {
|
|
3110
3153
|
onChange({
|
|
3111
3154
|
id: state.facet(documentId),
|
|
@@ -3120,7 +3163,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3120
3163
|
import { snippet } from "@codemirror/autocomplete";
|
|
3121
3164
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3122
3165
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3123
|
-
import { EditorView as
|
|
3166
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3124
3167
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3125
3168
|
var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
3126
3169
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4209,7 +4252,7 @@ var getFormatting = (state) => {
|
|
|
4209
4252
|
};
|
|
4210
4253
|
};
|
|
4211
4254
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4212
|
-
return
|
|
4255
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4213
4256
|
if (update2.docChanged || update2.selectionSet) {
|
|
4214
4257
|
onStateChange(getFormatting(update2.state));
|
|
4215
4258
|
}
|
|
@@ -4270,8 +4313,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4270
4313
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4271
4314
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4272
4315
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4273
|
-
import {
|
|
4274
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4316
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4275
4317
|
import { languages } from "@codemirror/language-data";
|
|
4276
4318
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4277
4319
|
import { isTruthy as isTruthy3 } from "@dxos/util";
|
|
@@ -4281,11 +4323,6 @@ import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
|
4281
4323
|
import { HighlightStyle as HighlightStyle2 } from "@codemirror/language";
|
|
4282
4324
|
import { Tag, styleTags, tags } from "@lezer/highlight";
|
|
4283
4325
|
import { Table } from "@lezer/markdown";
|
|
4284
|
-
var styles4 = {
|
|
4285
|
-
code: "font-mono no-underline! text-cm-code",
|
|
4286
|
-
codeMark: "font-mono text-cm-code-mark",
|
|
4287
|
-
mark: "opacity-50"
|
|
4288
|
-
};
|
|
4289
4326
|
var markdownTags = {
|
|
4290
4327
|
Blockquote: Tag.define(),
|
|
4291
4328
|
CodeMark: Tag.define(),
|
|
@@ -4367,7 +4404,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4367
4404
|
markdownTags.LinkReference,
|
|
4368
4405
|
markdownTags.ListMark
|
|
4369
4406
|
],
|
|
4370
|
-
class:
|
|
4407
|
+
class: markdownTheme.mark
|
|
4371
4408
|
},
|
|
4372
4409
|
// Markdown marks.
|
|
4373
4410
|
{
|
|
@@ -4378,7 +4415,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4378
4415
|
markdownTags.QuoteMark,
|
|
4379
4416
|
markdownTags.EmphasisMark
|
|
4380
4417
|
],
|
|
4381
|
-
class:
|
|
4418
|
+
class: markdownTheme.mark
|
|
4382
4419
|
},
|
|
4383
4420
|
// E.g., code block language (after ```).
|
|
4384
4421
|
{
|
|
@@ -4387,7 +4424,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4387
4424
|
tags.function(tags.variableName),
|
|
4388
4425
|
tags.labelName
|
|
4389
4426
|
],
|
|
4390
|
-
class:
|
|
4427
|
+
class: markdownTheme.codeMark
|
|
4391
4428
|
},
|
|
4392
4429
|
// Fonts.
|
|
4393
4430
|
{
|
|
@@ -4453,7 +4490,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4453
4490
|
markdownTags.CodeText,
|
|
4454
4491
|
markdownTags.InlineCode
|
|
4455
4492
|
],
|
|
4456
|
-
class:
|
|
4493
|
+
class: markdownTheme.code
|
|
4457
4494
|
},
|
|
4458
4495
|
{
|
|
4459
4496
|
tag: [
|
|
@@ -4483,15 +4520,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4483
4520
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4484
4521
|
base: markdownLanguage2,
|
|
4485
4522
|
// Languages for syntax highlighting fenced code blocks.
|
|
4523
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4486
4524
|
defaultCodeLanguage: jsonLanguage,
|
|
4487
|
-
codeLanguages:
|
|
4525
|
+
codeLanguages: [
|
|
4526
|
+
...options.codeLanguages ?? [],
|
|
4527
|
+
...languages
|
|
4528
|
+
],
|
|
4488
4529
|
// Don't complete HTML tags.
|
|
4489
4530
|
completeHTMLTags: false,
|
|
4490
4531
|
// Parser extensions.
|
|
4491
4532
|
extensions: [
|
|
4492
4533
|
// GFM provided by default.
|
|
4493
4534
|
markdownTagsExtensions,
|
|
4494
|
-
...options.extensions ?? defaultExtensions()
|
|
4535
|
+
...options.extensions ?? defaultExtensions(),
|
|
4536
|
+
// Disable folding for fenced code blocks by overriding foldNodeProp.
|
|
4537
|
+
// Note: returning null from foldService does not prevent syntaxFolding fallback,
|
|
4538
|
+
// so we must override the node prop directly on the FencedCode node type.
|
|
4539
|
+
noFencedCodeFolding
|
|
4495
4540
|
]
|
|
4496
4541
|
}),
|
|
4497
4542
|
// Custom styles.
|
|
@@ -4506,18 +4551,13 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4506
4551
|
].filter(isTruthy3))
|
|
4507
4552
|
];
|
|
4508
4553
|
};
|
|
4509
|
-
var
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
]
|
|
4515
|
-
|
|
4516
|
-
"xml",
|
|
4517
|
-
"xhtml"
|
|
4518
|
-
],
|
|
4519
|
-
load: async () => xml()
|
|
4520
|
-
});
|
|
4554
|
+
var noFencedCodeFolding = {
|
|
4555
|
+
props: [
|
|
4556
|
+
foldNodeProp.add({
|
|
4557
|
+
FencedCode: () => null
|
|
4558
|
+
})
|
|
4559
|
+
]
|
|
4560
|
+
};
|
|
4521
4561
|
var defaultExtensions = () => [
|
|
4522
4562
|
noSetExtHeading,
|
|
4523
4563
|
noHtml
|
|
@@ -4537,19 +4577,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4537
4577
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4538
4578
|
});
|
|
4539
4579
|
var convertTreeToJson = (state) => {
|
|
4540
|
-
const treeToJson = (
|
|
4580
|
+
const treeToJson = (cursor) => {
|
|
4541
4581
|
const node = {
|
|
4542
|
-
type:
|
|
4543
|
-
from:
|
|
4544
|
-
to:
|
|
4545
|
-
text: state.doc.slice(
|
|
4582
|
+
type: cursor.type.name,
|
|
4583
|
+
from: cursor.from,
|
|
4584
|
+
to: cursor.to,
|
|
4585
|
+
text: state.doc.slice(cursor.from, cursor.to).toString(),
|
|
4546
4586
|
children: []
|
|
4547
4587
|
};
|
|
4548
|
-
if (
|
|
4588
|
+
if (cursor.firstChild()) {
|
|
4549
4589
|
do {
|
|
4550
|
-
node.children.push(treeToJson(
|
|
4551
|
-
} while (
|
|
4552
|
-
|
|
4590
|
+
node.children.push(treeToJson(cursor));
|
|
4591
|
+
} while (cursor.nextSibling());
|
|
4592
|
+
cursor.parent();
|
|
4553
4593
|
}
|
|
4554
4594
|
return node;
|
|
4555
4595
|
};
|
|
@@ -4558,17 +4598,16 @@ var convertTreeToJson = (state) => {
|
|
|
4558
4598
|
|
|
4559
4599
|
// src/extensions/markdown/decorate.ts
|
|
4560
4600
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4561
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4562
|
-
import { Decoration as Decoration11, EditorView as
|
|
4601
|
+
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
|
|
4602
|
+
import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4563
4603
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4564
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4565
4604
|
|
|
4566
4605
|
// src/extensions/markdown/changes.ts
|
|
4567
4606
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4568
4607
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4569
|
-
import { ViewPlugin as
|
|
4608
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4570
4609
|
var adjustChanges = () => {
|
|
4571
|
-
return
|
|
4610
|
+
return ViewPlugin14.fromClass(class {
|
|
4572
4611
|
update(update2) {
|
|
4573
4612
|
const tree = syntaxTree4(update2.state);
|
|
4574
4613
|
const adjustments = [];
|
|
@@ -4710,7 +4749,7 @@ var getValidUrl = (str) => {
|
|
|
4710
4749
|
// src/extensions/markdown/image.ts
|
|
4711
4750
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4712
4751
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4713
|
-
import { Decoration as Decoration9, EditorView as
|
|
4752
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4714
4753
|
var image = (_options = {}) => {
|
|
4715
4754
|
return [
|
|
4716
4755
|
StateField7.define({
|
|
@@ -4721,10 +4760,10 @@ var image = (_options = {}) => {
|
|
|
4721
4760
|
if (!tr.docChanged && !tr.selection) {
|
|
4722
4761
|
return value;
|
|
4723
4762
|
}
|
|
4724
|
-
const
|
|
4763
|
+
const cursor = tr.state.selection.main.head;
|
|
4725
4764
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4726
|
-
let from = Math.min(
|
|
4727
|
-
let to = Math.max(
|
|
4765
|
+
let from = Math.min(cursor, oldCursor);
|
|
4766
|
+
let to = Math.max(cursor, oldCursor);
|
|
4728
4767
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4729
4768
|
from = Math.min(from, fromB);
|
|
4730
4769
|
to = Math.max(to, toB);
|
|
@@ -4738,19 +4777,19 @@ var image = (_options = {}) => {
|
|
|
4738
4777
|
add: buildDecorations(tr.state, from, to)
|
|
4739
4778
|
});
|
|
4740
4779
|
},
|
|
4741
|
-
provide: (field) =>
|
|
4780
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4742
4781
|
})
|
|
4743
4782
|
];
|
|
4744
4783
|
};
|
|
4745
4784
|
var buildDecorations = (state, from, to) => {
|
|
4746
4785
|
const decorations2 = [];
|
|
4747
|
-
const
|
|
4786
|
+
const cursor = state.selection.main.head;
|
|
4748
4787
|
syntaxTree5(state).iterate({
|
|
4749
4788
|
enter: (node) => {
|
|
4750
4789
|
if (node.name === "Image") {
|
|
4751
4790
|
const urlNode = node.node.getChild("URL");
|
|
4752
4791
|
if (urlNode) {
|
|
4753
|
-
const hide2 = state.readOnly ||
|
|
4792
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4754
4793
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4755
4794
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4756
4795
|
return;
|
|
@@ -4798,10 +4837,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4798
4837
|
};
|
|
4799
4838
|
|
|
4800
4839
|
// src/extensions/markdown/styles.ts
|
|
4801
|
-
import { EditorView as
|
|
4840
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4802
4841
|
var bulletListIndentationWidth = 24;
|
|
4803
4842
|
var orderedListIndentationWidth = 36;
|
|
4804
|
-
var formattingStyles =
|
|
4843
|
+
var formattingStyles = EditorView22.theme({
|
|
4805
4844
|
/**
|
|
4806
4845
|
* Horizontal rule.
|
|
4807
4846
|
*/
|
|
@@ -4836,13 +4875,38 @@ var formattingStyles = EditorView21.theme({
|
|
|
4836
4875
|
background: "var(--color-cm-codeblock)",
|
|
4837
4876
|
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4838
4877
|
paddingLeft: "1rem",
|
|
4839
|
-
margin:
|
|
4878
|
+
margin: 0
|
|
4840
4879
|
},
|
|
4841
4880
|
/**
|
|
4842
4881
|
* Code and codeblocks.
|
|
4843
4882
|
*/
|
|
4883
|
+
"& code": {
|
|
4884
|
+
fontFamily: fontMono,
|
|
4885
|
+
color: "var(--color-cm-code)",
|
|
4886
|
+
whiteSpace: "nowrap"
|
|
4887
|
+
},
|
|
4844
4888
|
"& .cm-code": {
|
|
4845
|
-
fontFamily: fontMono
|
|
4889
|
+
fontFamily: fontMono,
|
|
4890
|
+
color: "var(--color-cm-code)"
|
|
4891
|
+
},
|
|
4892
|
+
// Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
|
|
4893
|
+
// Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
|
|
4894
|
+
// so constrain them to the target 24px height.
|
|
4895
|
+
"& .cm-code-inline": {
|
|
4896
|
+
fontFamily: fontMono,
|
|
4897
|
+
height: "24px",
|
|
4898
|
+
// display: 'inline-flex',
|
|
4899
|
+
alignItems: "center",
|
|
4900
|
+
overflow: "hidden",
|
|
4901
|
+
whiteSpace: "nowrap",
|
|
4902
|
+
color: "var(--color-cm-code-inline)"
|
|
4903
|
+
},
|
|
4904
|
+
"& .cm-code-mark": {
|
|
4905
|
+
fontFamily: fontMono,
|
|
4906
|
+
height: "24px",
|
|
4907
|
+
display: "inline-flex",
|
|
4908
|
+
alignItems: "center",
|
|
4909
|
+
overflow: "hidden"
|
|
4846
4910
|
},
|
|
4847
4911
|
"& .cm-codeblock-line": {
|
|
4848
4912
|
background: "var(--color-cm-codeblock)",
|
|
@@ -4874,16 +4938,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4874
4938
|
*/
|
|
4875
4939
|
".cm-table *": {
|
|
4876
4940
|
fontFamily: fontMono,
|
|
4941
|
+
lineHeight: 1.5,
|
|
4877
4942
|
textDecoration: "none !important"
|
|
4878
4943
|
},
|
|
4879
4944
|
".cm-table-head": {
|
|
4880
4945
|
padding: "2px 16px 2px 0px",
|
|
4946
|
+
overflowWrap: "break-word",
|
|
4947
|
+
whiteSpace: "pre-wrap",
|
|
4948
|
+
wordBreak: "keep-all",
|
|
4881
4949
|
textAlign: "left",
|
|
4882
|
-
|
|
4883
|
-
|
|
4950
|
+
color: "var(--color-subdued)",
|
|
4951
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4884
4952
|
},
|
|
4885
4953
|
".cm-table-cell": {
|
|
4886
|
-
padding: "2px 16px 2px 0px"
|
|
4954
|
+
padding: "2px 16px 2px 0px",
|
|
4955
|
+
overflowWrap: "break-word",
|
|
4956
|
+
whiteSpace: "pre-wrap",
|
|
4957
|
+
wordBreak: "keep-all",
|
|
4958
|
+
verticalAlign: "top"
|
|
4887
4959
|
},
|
|
4888
4960
|
/**
|
|
4889
4961
|
* Image.
|
|
@@ -4899,12 +4971,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4899
4971
|
},
|
|
4900
4972
|
".cm-image-with-loader": {
|
|
4901
4973
|
display: "block",
|
|
4902
|
-
opacity:
|
|
4974
|
+
opacity: 0,
|
|
4903
4975
|
transitionDuration: "350ms",
|
|
4904
4976
|
transitionProperty: "opacity"
|
|
4905
4977
|
},
|
|
4906
4978
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4907
|
-
opacity:
|
|
4979
|
+
opacity: 1
|
|
4908
4980
|
},
|
|
4909
4981
|
".cm-image-wrapper": {
|
|
4910
4982
|
"grid-template-columns": "1fr",
|
|
@@ -4923,17 +4995,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4923
4995
|
// src/extensions/markdown/table.ts
|
|
4924
4996
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4925
4997
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4926
|
-
import { Decoration as Decoration10, EditorView as
|
|
4998
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4927
4999
|
var table = (options = {}) => {
|
|
4928
5000
|
return StateField8.define({
|
|
4929
5001
|
create: (state) => update(state, options),
|
|
4930
5002
|
update: (_, tr) => update(tr.state, options),
|
|
4931
|
-
provide: (field) =>
|
|
5003
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4932
5004
|
});
|
|
4933
5005
|
};
|
|
4934
5006
|
var update = (state, _options) => {
|
|
4935
5007
|
const builder = new RangeSetBuilder4();
|
|
4936
|
-
const
|
|
5008
|
+
const cursor = state.selection.main.head;
|
|
4937
5009
|
const tables = [];
|
|
4938
5010
|
const getTable = () => tables[tables.length - 1];
|
|
4939
5011
|
const getRow = () => {
|
|
@@ -4971,7 +5043,7 @@ var update = (state, _options) => {
|
|
|
4971
5043
|
}
|
|
4972
5044
|
});
|
|
4973
5045
|
tables.forEach((table2) => {
|
|
4974
|
-
const replace = state.readOnly ||
|
|
5046
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4975
5047
|
if (replace) {
|
|
4976
5048
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4977
5049
|
block: true,
|
|
@@ -4985,6 +5057,26 @@ var update = (state, _options) => {
|
|
|
4985
5057
|
});
|
|
4986
5058
|
return builder.finish();
|
|
4987
5059
|
};
|
|
5060
|
+
var renderCellContent = (el, text) => {
|
|
5061
|
+
const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
|
|
5062
|
+
for (const part of parts) {
|
|
5063
|
+
if (part.length > 2 && part.startsWith("`") && part.endsWith("`")) {
|
|
5064
|
+
const code = document.createElement("code");
|
|
5065
|
+
code.textContent = part.slice(1, -1);
|
|
5066
|
+
el.appendChild(code);
|
|
5067
|
+
} else if (part.startsWith("**") && part.endsWith("**") || part.startsWith("__") && part.endsWith("__")) {
|
|
5068
|
+
const strong = document.createElement("strong");
|
|
5069
|
+
strong.textContent = part.slice(2, -2);
|
|
5070
|
+
el.appendChild(strong);
|
|
5071
|
+
} else if (part.startsWith("*") && part.endsWith("*") || part.startsWith("_") && part.endsWith("_")) {
|
|
5072
|
+
const em = document.createElement("em");
|
|
5073
|
+
em.textContent = part.slice(1, -1);
|
|
5074
|
+
el.appendChild(em);
|
|
5075
|
+
} else {
|
|
5076
|
+
el.appendChild(document.createTextNode(part));
|
|
5077
|
+
}
|
|
5078
|
+
}
|
|
5079
|
+
};
|
|
4988
5080
|
var TableWidget = class extends WidgetType6 {
|
|
4989
5081
|
_table;
|
|
4990
5082
|
constructor(_table) {
|
|
@@ -5004,7 +5096,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
5004
5096
|
this._table.header?.forEach((cell) => {
|
|
5005
5097
|
const th = document.createElement("th");
|
|
5006
5098
|
th.setAttribute("class", "cm-table-head");
|
|
5007
|
-
tr.appendChild(th)
|
|
5099
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
5008
5100
|
});
|
|
5009
5101
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
5010
5102
|
this._table.rows?.forEach((row) => {
|
|
@@ -5012,7 +5104,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
5012
5104
|
row.forEach((cell) => {
|
|
5013
5105
|
const td = document.createElement("td");
|
|
5014
5106
|
td.setAttribute("class", "cm-table-cell");
|
|
5015
|
-
tr2.appendChild(td)
|
|
5107
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
5016
5108
|
});
|
|
5017
5109
|
});
|
|
5018
5110
|
return div;
|
|
@@ -5119,10 +5211,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5119
5211
|
class: "cm-code cm-codeblock-line"
|
|
5120
5212
|
});
|
|
5121
5213
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5122
|
-
class:
|
|
5214
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5123
5215
|
});
|
|
5124
5216
|
var fencedCodeLineLast = Decoration11.line({
|
|
5125
|
-
class:
|
|
5217
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5126
5218
|
});
|
|
5127
5219
|
var commentBlockLine = fencedCodeLine;
|
|
5128
5220
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5154,15 +5246,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5154
5246
|
const { state } = view;
|
|
5155
5247
|
const headerLevels = [];
|
|
5156
5248
|
const getHeaderLevels = (node, level) => {
|
|
5157
|
-
invariant4(level > 0, void 0, {
|
|
5158
|
-
F: __dxlog_file12,
|
|
5159
|
-
L: 179,
|
|
5160
|
-
S: void 0,
|
|
5161
|
-
A: [
|
|
5162
|
-
"level > 0",
|
|
5163
|
-
""
|
|
5164
|
-
]
|
|
5165
|
-
});
|
|
5249
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5166
5250
|
if (level > headerLevels.length) {
|
|
5167
5251
|
const len = headerLevels.length;
|
|
5168
5252
|
headerLevels.length = level;
|
|
@@ -5193,15 +5277,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5193
5277
|
listLevels.pop();
|
|
5194
5278
|
};
|
|
5195
5279
|
const getCurrentListLevel = () => {
|
|
5196
|
-
invariant4(listLevels.length, void 0, {
|
|
5197
|
-
F: __dxlog_file12,
|
|
5198
|
-
L: 201,
|
|
5199
|
-
S: void 0,
|
|
5200
|
-
A: [
|
|
5201
|
-
"listLevels.length",
|
|
5202
|
-
""
|
|
5203
|
-
]
|
|
5204
|
-
});
|
|
5280
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5205
5281
|
return listLevels[listLevels.length - 1];
|
|
5206
5282
|
};
|
|
5207
5283
|
const enterNode = (node) => {
|
|
@@ -5239,7 +5315,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5239
5315
|
deco: hide
|
|
5240
5316
|
});
|
|
5241
5317
|
} else {
|
|
5242
|
-
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
|
5318
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + "). ";
|
|
5243
5319
|
if (num.length) {
|
|
5244
5320
|
atomicDecoRanges.push({
|
|
5245
5321
|
from: mark.from,
|
|
@@ -5422,11 +5498,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5422
5498
|
}
|
|
5423
5499
|
decoRanges.push({
|
|
5424
5500
|
from: marks[0].to,
|
|
5425
|
-
to: marks[1].from,
|
|
5501
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5426
5502
|
deco: Decoration11.mark({
|
|
5427
5503
|
tagName: "a",
|
|
5428
5504
|
attributes: {
|
|
5429
|
-
class: "cm-link",
|
|
5505
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5430
5506
|
href: url,
|
|
5431
5507
|
rel: "noreferrer",
|
|
5432
5508
|
target: "_blank"
|
|
@@ -5504,18 +5580,21 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5504
5580
|
deco.add(from, to, d);
|
|
5505
5581
|
}
|
|
5506
5582
|
const atomicDeco = new RangeSetBuilder5();
|
|
5507
|
-
for (const { from, to, deco:
|
|
5508
|
-
|
|
5583
|
+
for (const { from, to, deco: deco2 } of atomicDecoRanges) {
|
|
5584
|
+
if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
|
|
5585
|
+
continue;
|
|
5586
|
+
}
|
|
5587
|
+
atomicDeco.add(from, to, deco2);
|
|
5509
5588
|
}
|
|
5510
5589
|
return {
|
|
5511
5590
|
deco: deco.finish(),
|
|
5512
5591
|
atomicDeco: atomicDeco.finish()
|
|
5513
5592
|
};
|
|
5514
5593
|
};
|
|
5515
|
-
var forceUpdate =
|
|
5594
|
+
var forceUpdate = StateEffect7.define();
|
|
5516
5595
|
var decorateMarkdown = (options = {}) => {
|
|
5517
5596
|
return [
|
|
5518
|
-
|
|
5597
|
+
ViewPlugin15.fromClass(class {
|
|
5519
5598
|
deco;
|
|
5520
5599
|
atomicDeco;
|
|
5521
5600
|
pendingUpdate;
|
|
@@ -5550,9 +5629,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5550
5629
|
}
|
|
5551
5630
|
}, {
|
|
5552
5631
|
provide: (plugin) => [
|
|
5553
|
-
Prec4.low(
|
|
5554
|
-
|
|
5555
|
-
|
|
5632
|
+
Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5633
|
+
EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5634
|
+
EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5556
5635
|
]
|
|
5557
5636
|
}),
|
|
5558
5637
|
image(),
|
|
@@ -5620,12 +5699,7 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5620
5699
|
(context) => {
|
|
5621
5700
|
log9.info("completion context", {
|
|
5622
5701
|
context
|
|
5623
|
-
}, {
|
|
5624
|
-
F: __dxlog_file13,
|
|
5625
|
-
L: 27,
|
|
5626
|
-
S: void 0,
|
|
5627
|
-
C: (f, a) => f(...a)
|
|
5628
|
-
});
|
|
5702
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5629
5703
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5630
5704
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5631
5705
|
return null;
|
|
@@ -5642,8 +5716,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5642
5716
|
};
|
|
5643
5717
|
|
|
5644
5718
|
// src/extensions/modal.ts
|
|
5645
|
-
import { StateEffect as
|
|
5646
|
-
var modalStateEffect =
|
|
5719
|
+
import { StateEffect as StateEffect8, StateField as StateField9 } from "@codemirror/state";
|
|
5720
|
+
var modalStateEffect = StateEffect8.define();
|
|
5647
5721
|
var modalStateField = StateField9.define({
|
|
5648
5722
|
create: () => false,
|
|
5649
5723
|
update: (value, tr) => {
|
|
@@ -5858,15 +5932,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5858
5932
|
break;
|
|
5859
5933
|
}
|
|
5860
5934
|
case "BulletList": {
|
|
5861
|
-
invariant5(current, void 0, {
|
|
5862
|
-
F: __dxlog_file14,
|
|
5863
|
-
L: 219,
|
|
5864
|
-
S: void 0,
|
|
5865
|
-
A: [
|
|
5866
|
-
"current",
|
|
5867
|
-
""
|
|
5868
|
-
]
|
|
5869
|
-
});
|
|
5935
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5870
5936
|
parent = current;
|
|
5871
5937
|
if (current) {
|
|
5872
5938
|
current.lineRange.to = current.node.from;
|
|
@@ -5875,15 +5941,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5875
5941
|
break;
|
|
5876
5942
|
}
|
|
5877
5943
|
case "ListItem": {
|
|
5878
|
-
invariant5(parent, void 0, {
|
|
5879
|
-
F: __dxlog_file14,
|
|
5880
|
-
L: 228,
|
|
5881
|
-
S: void 0,
|
|
5882
|
-
A: [
|
|
5883
|
-
"parent",
|
|
5884
|
-
""
|
|
5885
|
-
]
|
|
5886
|
-
});
|
|
5944
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5887
5945
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5888
5946
|
const docRange = {
|
|
5889
5947
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5917,42 +5975,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5917
5975
|
break;
|
|
5918
5976
|
}
|
|
5919
5977
|
case "ListMark": {
|
|
5920
|
-
invariant5(current, void 0, {
|
|
5921
|
-
F: __dxlog_file14,
|
|
5922
|
-
L: 272,
|
|
5923
|
-
S: void 0,
|
|
5924
|
-
A: [
|
|
5925
|
-
"current",
|
|
5926
|
-
""
|
|
5927
|
-
]
|
|
5928
|
-
});
|
|
5978
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5929
5979
|
current.type = "bullet";
|
|
5930
5980
|
current.contentRange.from = node.from + "- ".length;
|
|
5931
5981
|
break;
|
|
5932
5982
|
}
|
|
5933
5983
|
case "Task": {
|
|
5934
|
-
invariant5(current, void 0, {
|
|
5935
|
-
F: __dxlog_file14,
|
|
5936
|
-
L: 278,
|
|
5937
|
-
S: void 0,
|
|
5938
|
-
A: [
|
|
5939
|
-
"current",
|
|
5940
|
-
""
|
|
5941
|
-
]
|
|
5942
|
-
});
|
|
5984
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5943
5985
|
current.type = "task";
|
|
5944
5986
|
break;
|
|
5945
5987
|
}
|
|
5946
5988
|
case "TaskMarker": {
|
|
5947
|
-
invariant5(current, void 0, {
|
|
5948
|
-
F: __dxlog_file14,
|
|
5949
|
-
L: 283,
|
|
5950
|
-
S: void 0,
|
|
5951
|
-
A: [
|
|
5952
|
-
"current",
|
|
5953
|
-
""
|
|
5954
|
-
]
|
|
5955
|
-
});
|
|
5989
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5956
5990
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5957
5991
|
break;
|
|
5958
5992
|
}
|
|
@@ -5960,29 +5994,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5960
5994
|
},
|
|
5961
5995
|
leave: (node) => {
|
|
5962
5996
|
if (node.name === "BulletList") {
|
|
5963
|
-
invariant5(parent, void 0, {
|
|
5964
|
-
F: __dxlog_file14,
|
|
5965
|
-
L: 291,
|
|
5966
|
-
S: void 0,
|
|
5967
|
-
A: [
|
|
5968
|
-
"parent",
|
|
5969
|
-
""
|
|
5970
|
-
]
|
|
5971
|
-
});
|
|
5997
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5972
5998
|
prevSiblings[level--] = void 0;
|
|
5973
5999
|
parent = parent.parent;
|
|
5974
6000
|
}
|
|
5975
6001
|
}
|
|
5976
6002
|
});
|
|
5977
|
-
invariant5(tree, void 0, {
|
|
5978
|
-
F: __dxlog_file14,
|
|
5979
|
-
L: 298,
|
|
5980
|
-
S: void 0,
|
|
5981
|
-
A: [
|
|
5982
|
-
"tree",
|
|
5983
|
-
""
|
|
5984
|
-
]
|
|
5985
|
-
});
|
|
6003
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5986
6004
|
return tree;
|
|
5987
6005
|
};
|
|
5988
6006
|
return [
|
|
@@ -6267,17 +6285,17 @@ var commands = () => keymap11.of([
|
|
|
6267
6285
|
|
|
6268
6286
|
// src/extensions/outliner/outliner.ts
|
|
6269
6287
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6270
|
-
import { Decoration as Decoration12, EditorView as
|
|
6271
|
-
import { mx as
|
|
6288
|
+
import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6289
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
6272
6290
|
|
|
6273
6291
|
// src/extensions/outliner/editor.ts
|
|
6274
6292
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6275
|
-
import { ViewPlugin as
|
|
6293
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6276
6294
|
import { log as log10 } from "@dxos/log";
|
|
6277
6295
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6278
6296
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6279
6297
|
var initialize = () => {
|
|
6280
|
-
return
|
|
6298
|
+
return ViewPlugin16.fromClass(class {
|
|
6281
6299
|
constructor(view) {
|
|
6282
6300
|
const first = view.state.doc.lineAt(0);
|
|
6283
6301
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6424,35 +6442,20 @@ var editor = () => [
|
|
|
6424
6442
|
text: insert.toString(),
|
|
6425
6443
|
length: insert.length
|
|
6426
6444
|
}
|
|
6427
|
-
}, {
|
|
6428
|
-
F: __dxlog_file15,
|
|
6429
|
-
L: 164,
|
|
6430
|
-
S: void 0,
|
|
6431
|
-
C: (f, a) => f(...a)
|
|
6432
|
-
});
|
|
6445
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6433
6446
|
}
|
|
6434
6447
|
});
|
|
6435
6448
|
if (changes.length > 0) {
|
|
6436
6449
|
log10("modified,", {
|
|
6437
6450
|
changes
|
|
6438
|
-
}, {
|
|
6439
|
-
F: __dxlog_file15,
|
|
6440
|
-
L: 175,
|
|
6441
|
-
S: void 0,
|
|
6442
|
-
C: (f, a) => f(...a)
|
|
6443
|
-
});
|
|
6451
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6444
6452
|
return [
|
|
6445
6453
|
{
|
|
6446
6454
|
changes
|
|
6447
6455
|
}
|
|
6448
6456
|
];
|
|
6449
6457
|
} else if (cancel) {
|
|
6450
|
-
log10("cancel", void 0, {
|
|
6451
|
-
F: __dxlog_file15,
|
|
6452
|
-
L: 178,
|
|
6453
|
-
S: void 0,
|
|
6454
|
-
C: (f, a) => f(...a)
|
|
6455
|
-
});
|
|
6458
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6456
6459
|
return [];
|
|
6457
6460
|
}
|
|
6458
6461
|
return tr;
|
|
@@ -6460,10 +6463,10 @@ var editor = () => [
|
|
|
6460
6463
|
];
|
|
6461
6464
|
|
|
6462
6465
|
// src/extensions/outliner/menu.ts
|
|
6463
|
-
import { EditorView as
|
|
6466
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6464
6467
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6465
6468
|
var menu = (options = {}) => [
|
|
6466
|
-
|
|
6469
|
+
ViewPlugin17.fromClass(class {
|
|
6467
6470
|
view;
|
|
6468
6471
|
tag;
|
|
6469
6472
|
rafId;
|
|
@@ -6525,7 +6528,7 @@ var menu = (options = {}) => [
|
|
|
6525
6528
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6526
6529
|
}
|
|
6527
6530
|
}),
|
|
6528
|
-
|
|
6531
|
+
EditorView25.theme({
|
|
6529
6532
|
".cm-popover-trigger": {
|
|
6530
6533
|
position: "fixed",
|
|
6531
6534
|
padding: "0",
|
|
@@ -6561,12 +6564,12 @@ var outliner = (_options = {}) => [
|
|
|
6561
6564
|
listPaddingLeft: 8
|
|
6562
6565
|
}),
|
|
6563
6566
|
// Researve space for menu.
|
|
6564
|
-
|
|
6567
|
+
EditorView26.contentAttributes.of({
|
|
6565
6568
|
class: "w-full !mr-[3rem]"
|
|
6566
6569
|
})
|
|
6567
6570
|
];
|
|
6568
6571
|
var decorations = () => [
|
|
6569
|
-
|
|
6572
|
+
ViewPlugin18.fromClass(class {
|
|
6570
6573
|
decorations = Decoration12.none;
|
|
6571
6574
|
constructor(view) {
|
|
6572
6575
|
this.updateDecorations(view.state, view);
|
|
@@ -6591,7 +6594,7 @@ var decorations = () => [
|
|
|
6591
6594
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6592
6595
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6593
6596
|
decorations2.push(Decoration12.line({
|
|
6594
|
-
class:
|
|
6597
|
+
class: mx6("cm-list-item", lineFrom.number === line.number && "cm-list-item-start", lineTo.number === line.number && "cm-list-item-end", isSelected && (hasFocus ? "cm-list-item-focused" : "cm-list-item-selected"))
|
|
6595
6598
|
}).range(line.from, line.from));
|
|
6596
6599
|
}
|
|
6597
6600
|
}
|
|
@@ -6601,7 +6604,7 @@ var decorations = () => [
|
|
|
6601
6604
|
decorations: (v) => v.decorations
|
|
6602
6605
|
}),
|
|
6603
6606
|
// Theme.
|
|
6604
|
-
|
|
6607
|
+
EditorView26.theme(Object.assign({
|
|
6605
6608
|
".cm-list-item": {
|
|
6606
6609
|
borderLeftWidth: "1px",
|
|
6607
6610
|
borderRightWidth: "1px",
|
|
@@ -6636,28 +6639,57 @@ var decorations = () => [
|
|
|
6636
6639
|
|
|
6637
6640
|
// src/extensions/preview/preview.ts
|
|
6638
6641
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6639
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
|
|
6640
|
-
import { Decoration as Decoration13, EditorView as
|
|
6642
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
|
|
6643
|
+
import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6644
|
+
import { DXN, Entity } from "@dxos/echo";
|
|
6645
|
+
var labelResolvedEffect = StateEffect9.define();
|
|
6641
6646
|
var preview = (options = {}) => {
|
|
6647
|
+
const viewRef = {
|
|
6648
|
+
current: void 0
|
|
6649
|
+
};
|
|
6642
6650
|
return [
|
|
6643
6651
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6644
6652
|
// "Block decorations may not be specified via plugins".
|
|
6645
6653
|
StateField11.define({
|
|
6646
|
-
create: (state) => buildDecorations3(state, options),
|
|
6654
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6647
6655
|
update: (decorations2, tr) => {
|
|
6648
|
-
if (tr.docChanged) {
|
|
6649
|
-
return buildDecorations3(tr.state, options);
|
|
6656
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6657
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6650
6658
|
}
|
|
6651
6659
|
return decorations2.map(tr.changes);
|
|
6652
6660
|
},
|
|
6653
6661
|
provide: (field) => [
|
|
6654
|
-
|
|
6655
|
-
|
|
6662
|
+
EditorView27.decorations.from(field),
|
|
6663
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6656
6664
|
]
|
|
6665
|
+
}),
|
|
6666
|
+
ViewPlugin19.define((view) => {
|
|
6667
|
+
viewRef.current = view;
|
|
6668
|
+
return {
|
|
6669
|
+
destroy() {
|
|
6670
|
+
viewRef.current = void 0;
|
|
6671
|
+
}
|
|
6672
|
+
};
|
|
6657
6673
|
})
|
|
6658
6674
|
];
|
|
6659
6675
|
};
|
|
6660
|
-
var
|
|
6676
|
+
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6677
|
+
const dxn = DXN.tryParse(dxnStr);
|
|
6678
|
+
if (!dxn) {
|
|
6679
|
+
return;
|
|
6680
|
+
}
|
|
6681
|
+
const ref = db.makeRef(dxn);
|
|
6682
|
+
const target = ref.target;
|
|
6683
|
+
if (target) {
|
|
6684
|
+
return Entity.getLabel(target);
|
|
6685
|
+
}
|
|
6686
|
+
void ref.tryLoad().then(() => {
|
|
6687
|
+
viewRef.current?.dispatch({
|
|
6688
|
+
effects: labelResolvedEffect.of(void 0)
|
|
6689
|
+
});
|
|
6690
|
+
});
|
|
6691
|
+
};
|
|
6692
|
+
var buildDecorations3 = (state, options, viewRef) => {
|
|
6661
6693
|
const builder = new RangeSetBuilder6();
|
|
6662
6694
|
syntaxTree10(state).iterate({
|
|
6663
6695
|
enter: (node) => {
|
|
@@ -6669,8 +6701,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6669
6701
|
case "Link": {
|
|
6670
6702
|
const link = getLinkRef(state, node.node);
|
|
6671
6703
|
if (link) {
|
|
6704
|
+
const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : void 0;
|
|
6705
|
+
const displayLink = resolved ? {
|
|
6706
|
+
...link,
|
|
6707
|
+
label: resolved
|
|
6708
|
+
} : link;
|
|
6672
6709
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6673
|
-
widget: new PreviewInlineWidget(options,
|
|
6710
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6674
6711
|
side: 1
|
|
6675
6712
|
}));
|
|
6676
6713
|
}
|
|
@@ -6762,7 +6799,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6762
6799
|
};
|
|
6763
6800
|
|
|
6764
6801
|
// src/extensions/replacer.ts
|
|
6765
|
-
import { EditorView as
|
|
6802
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6766
6803
|
var defaultReplacements = [
|
|
6767
6804
|
{
|
|
6768
6805
|
input: "--",
|
|
@@ -6825,7 +6862,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6825
6862
|
const sortedReplacements = [
|
|
6826
6863
|
...replacements
|
|
6827
6864
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6828
|
-
return
|
|
6865
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6829
6866
|
if (insert.length !== 1) {
|
|
6830
6867
|
return false;
|
|
6831
6868
|
}
|
|
@@ -6859,12 +6896,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6859
6896
|
});
|
|
6860
6897
|
};
|
|
6861
6898
|
|
|
6899
|
+
// src/extensions/snippets.ts
|
|
6900
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
6901
|
+
var defaultItems = [
|
|
6902
|
+
"hello world!",
|
|
6903
|
+
"this is a test.",
|
|
6904
|
+
"this is [DXOS](https://dxos.org)"
|
|
6905
|
+
];
|
|
6906
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
6907
|
+
let timer;
|
|
6908
|
+
let index = 0;
|
|
6909
|
+
return [
|
|
6910
|
+
keymap12.of([
|
|
6911
|
+
{
|
|
6912
|
+
// Reset.
|
|
6913
|
+
key: "alt-meta-'",
|
|
6914
|
+
run: () => {
|
|
6915
|
+
clearTimeout(timer);
|
|
6916
|
+
index = 0;
|
|
6917
|
+
return true;
|
|
6918
|
+
}
|
|
6919
|
+
},
|
|
6920
|
+
{
|
|
6921
|
+
// Next snippet.
|
|
6922
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
6923
|
+
key: "Shift-Meta-'",
|
|
6924
|
+
run: (view) => {
|
|
6925
|
+
clearTimeout(timer);
|
|
6926
|
+
const text = items[index++];
|
|
6927
|
+
if (index === items?.length) {
|
|
6928
|
+
index = 0;
|
|
6929
|
+
}
|
|
6930
|
+
let offset = 0;
|
|
6931
|
+
const insert = (delayMs = 0) => {
|
|
6932
|
+
timer = setTimeout(() => {
|
|
6933
|
+
const pos = view.state.selection.main.head;
|
|
6934
|
+
view.dispatch({
|
|
6935
|
+
changes: {
|
|
6936
|
+
from: pos,
|
|
6937
|
+
insert: text[offset++]
|
|
6938
|
+
},
|
|
6939
|
+
selection: {
|
|
6940
|
+
anchor: pos + 1
|
|
6941
|
+
}
|
|
6942
|
+
});
|
|
6943
|
+
if (offset < text.length) {
|
|
6944
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
6945
|
+
}
|
|
6946
|
+
}, delayMs);
|
|
6947
|
+
};
|
|
6948
|
+
insert();
|
|
6949
|
+
return true;
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
])
|
|
6953
|
+
];
|
|
6954
|
+
};
|
|
6955
|
+
|
|
6862
6956
|
// src/extensions/submit.ts
|
|
6863
6957
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6864
|
-
import { keymap as
|
|
6958
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6865
6959
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6866
6960
|
return [
|
|
6867
|
-
Prec6.highest(
|
|
6961
|
+
Prec6.highest(keymap13.of([
|
|
6868
6962
|
{
|
|
6869
6963
|
key: "Enter",
|
|
6870
6964
|
preventDefault: true,
|
|
@@ -6909,6 +7003,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6909
7003
|
// src/extensions/tags/extended-markdown.ts
|
|
6910
7004
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6911
7005
|
import { parseMixed } from "@lezer/common";
|
|
7006
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6912
7007
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6913
7008
|
return [
|
|
6914
7009
|
createMarkdownExtensions({
|
|
@@ -6920,13 +7015,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6920
7015
|
{
|
|
6921
7016
|
name: "SetextHeading",
|
|
6922
7017
|
parse: () => false
|
|
6923
|
-
}
|
|
7018
|
+
},
|
|
7019
|
+
// Custom XML block parser that keeps registered tags as a single HTMLBlock
|
|
7020
|
+
// even when their content contains blank lines.
|
|
7021
|
+
...xmlBlockParsers(registry)
|
|
6924
7022
|
]
|
|
6925
7023
|
}
|
|
6926
7024
|
]
|
|
6927
7025
|
})
|
|
6928
7026
|
];
|
|
6929
7027
|
};
|
|
7028
|
+
var xmlBlockParsers = (registry) => {
|
|
7029
|
+
const customTags = Object.keys(registry ?? {});
|
|
7030
|
+
if (customTags.length === 0) {
|
|
7031
|
+
return [];
|
|
7032
|
+
}
|
|
7033
|
+
const tagPattern = customTags.map(escapeRegExpSource).join("|");
|
|
7034
|
+
const selfClosePattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/>\\s*$`);
|
|
7035
|
+
const openPattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/?>`);
|
|
7036
|
+
return [
|
|
7037
|
+
{
|
|
7038
|
+
name: "XMLBlock",
|
|
7039
|
+
before: "HTMLBlock",
|
|
7040
|
+
parse: (cx, line) => {
|
|
7041
|
+
const match = openPattern.exec(line.text);
|
|
7042
|
+
if (!match) {
|
|
7043
|
+
return false;
|
|
7044
|
+
}
|
|
7045
|
+
if (selfClosePattern.test(line.text)) {
|
|
7046
|
+
const end2 = cx.lineStart + line.text.length;
|
|
7047
|
+
cx.addElement(cx.elt("HTMLBlock", cx.lineStart, end2));
|
|
7048
|
+
cx.nextLine();
|
|
7049
|
+
return true;
|
|
7050
|
+
}
|
|
7051
|
+
if (match[0].trimEnd().endsWith("/>")) {
|
|
7052
|
+
return false;
|
|
7053
|
+
}
|
|
7054
|
+
const tagName = match[1];
|
|
7055
|
+
const closeTag = `</${tagName}>`;
|
|
7056
|
+
const start = cx.lineStart;
|
|
7057
|
+
if (line.text.includes(closeTag)) {
|
|
7058
|
+
cx.addElement(cx.elt("HTMLBlock", start, start + line.text.length));
|
|
7059
|
+
cx.nextLine();
|
|
7060
|
+
return true;
|
|
7061
|
+
}
|
|
7062
|
+
let end = cx.lineStart + line.text.length;
|
|
7063
|
+
while (cx.nextLine()) {
|
|
7064
|
+
end = cx.lineStart + line.text.length;
|
|
7065
|
+
if (line.text.includes(closeTag)) {
|
|
7066
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7067
|
+
cx.nextLine();
|
|
7068
|
+
return true;
|
|
7069
|
+
}
|
|
7070
|
+
}
|
|
7071
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7072
|
+
return true;
|
|
7073
|
+
}
|
|
7074
|
+
}
|
|
7075
|
+
];
|
|
7076
|
+
};
|
|
6930
7077
|
var mixedParser = (registry) => {
|
|
6931
7078
|
const customTags = Object.keys(registry ?? {});
|
|
6932
7079
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6960,219 +7107,793 @@ var mixedParser = (registry) => {
|
|
|
6960
7107
|
});
|
|
6961
7108
|
};
|
|
6962
7109
|
|
|
6963
|
-
// src/extensions/tags/
|
|
6964
|
-
import { StateEffect as
|
|
6965
|
-
import { Decoration as Decoration14, EditorView as
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
var
|
|
6969
|
-
var
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
7110
|
+
// src/extensions/tags/fader.ts
|
|
7111
|
+
import { StateEffect as StateEffect10, StateField as StateField12 } from "@codemirror/state";
|
|
7112
|
+
import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
7113
|
+
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7114
|
+
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7115
|
+
var CLEANUP_INTERVAL = 1e3;
|
|
7116
|
+
var fader = (options = {}) => {
|
|
7117
|
+
const removalDelay = DEFAULT_REMOVAL_DELAY;
|
|
7118
|
+
const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;
|
|
7119
|
+
let lastCount = -1;
|
|
7120
|
+
const log12 = (expiries) => {
|
|
7121
|
+
if (expiries.length !== lastCount) {
|
|
7122
|
+
lastCount = expiries.length;
|
|
7123
|
+
}
|
|
7124
|
+
};
|
|
7125
|
+
const dequeue = StateEffect10.define();
|
|
7126
|
+
const fadeField = StateField12.define({
|
|
7127
|
+
create: () => ({
|
|
7128
|
+
decorations: Decoration14.none,
|
|
7129
|
+
expiries: [],
|
|
7130
|
+
batchStart: 0
|
|
7131
|
+
}),
|
|
7132
|
+
update: ({ decorations: decorations2, expiries, batchStart }, tr) => {
|
|
6980
7133
|
for (const effect of tr.effects) {
|
|
6981
|
-
if (effect.is(
|
|
6982
|
-
|
|
7134
|
+
if (effect.is(dequeue)) {
|
|
7135
|
+
const now2 = effect.value;
|
|
7136
|
+
let removeCount = 0;
|
|
7137
|
+
while (removeCount < expiries.length && expiries[removeCount] <= now2) {
|
|
7138
|
+
removeCount++;
|
|
7139
|
+
}
|
|
7140
|
+
if (removeCount > 0) {
|
|
7141
|
+
expiries = expiries.slice(removeCount);
|
|
7142
|
+
let skipped = 0;
|
|
7143
|
+
decorations2 = decorations2.update({
|
|
7144
|
+
filter: () => {
|
|
7145
|
+
if (skipped < removeCount) {
|
|
7146
|
+
skipped++;
|
|
7147
|
+
return false;
|
|
7148
|
+
}
|
|
7149
|
+
return true;
|
|
7150
|
+
}
|
|
7151
|
+
});
|
|
7152
|
+
}
|
|
6983
7153
|
}
|
|
6984
7154
|
}
|
|
6985
|
-
if (tr.docChanged) {
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
7155
|
+
if (!tr.docChanged) {
|
|
7156
|
+
log12(expiries);
|
|
7157
|
+
return {
|
|
7158
|
+
decorations: decorations2,
|
|
7159
|
+
expiries,
|
|
7160
|
+
batchStart
|
|
7161
|
+
};
|
|
7162
|
+
}
|
|
7163
|
+
let isReset = tr.state.doc.length === 0;
|
|
7164
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7165
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7166
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7167
|
+
isReset = true;
|
|
7168
|
+
}
|
|
7169
|
+
});
|
|
7170
|
+
}
|
|
7171
|
+
if (isReset) {
|
|
7172
|
+
log12([]);
|
|
7173
|
+
return {
|
|
7174
|
+
decorations: Decoration14.none,
|
|
7175
|
+
expiries: [],
|
|
7176
|
+
batchStart: 0
|
|
7177
|
+
};
|
|
7178
|
+
}
|
|
7179
|
+
const now = Date.now();
|
|
7180
|
+
const add = [];
|
|
7181
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
7182
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
7183
|
+
add.push({
|
|
7184
|
+
from: fromB,
|
|
7185
|
+
to: toB
|
|
7186
|
+
});
|
|
7187
|
+
}
|
|
7188
|
+
});
|
|
7189
|
+
if (add.length > 0) {
|
|
7190
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
7191
|
+
if (canCoalesce) {
|
|
7192
|
+
let lastFrom = -1;
|
|
7193
|
+
let lastTo = -1;
|
|
7194
|
+
decorations2.between(0, tr.state.doc.length, (from, to) => {
|
|
7195
|
+
lastFrom = from;
|
|
7196
|
+
lastTo = to;
|
|
7197
|
+
});
|
|
7198
|
+
if (lastFrom >= 0) {
|
|
7199
|
+
decorations2 = decorations2.update({
|
|
7200
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo)
|
|
7201
|
+
});
|
|
7202
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
7203
|
+
const mergedTo = add[add.length - 1].to;
|
|
7204
|
+
decorations2 = decorations2.update({
|
|
7205
|
+
add: [
|
|
7206
|
+
Decoration14.mark({
|
|
7207
|
+
class: "cm-fader"
|
|
7208
|
+
}).range(mergedFrom, mergedTo)
|
|
7209
|
+
]
|
|
7210
|
+
});
|
|
7211
|
+
expiries = [
|
|
7212
|
+
...expiries.slice(0, -1),
|
|
7213
|
+
now + removalDelay
|
|
7214
|
+
];
|
|
7215
|
+
}
|
|
7216
|
+
} else {
|
|
7217
|
+
batchStart = now;
|
|
7218
|
+
expiries = [
|
|
7219
|
+
...expiries,
|
|
7220
|
+
now + removalDelay
|
|
7221
|
+
];
|
|
7222
|
+
decorations2 = decorations2.update({
|
|
7223
|
+
add: add.map(({ from, to }) => Decoration14.mark({
|
|
7224
|
+
class: "cm-fader"
|
|
7225
|
+
}).range(from, to))
|
|
7226
|
+
});
|
|
7227
|
+
}
|
|
7228
|
+
}
|
|
7229
|
+
log12(expiries);
|
|
7230
|
+
return {
|
|
7231
|
+
decorations: decorations2,
|
|
7232
|
+
expiries,
|
|
7233
|
+
batchStart
|
|
7234
|
+
};
|
|
7235
|
+
},
|
|
7236
|
+
provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
|
|
7237
|
+
});
|
|
7238
|
+
const cleanup = ViewPlugin20.fromClass(class {
|
|
7239
|
+
view;
|
|
7240
|
+
#timer;
|
|
7241
|
+
constructor(view) {
|
|
7242
|
+
this.view = view;
|
|
7243
|
+
this.#schedule();
|
|
7244
|
+
}
|
|
7245
|
+
update() {
|
|
7246
|
+
this.#schedule();
|
|
7247
|
+
}
|
|
7248
|
+
#schedule() {
|
|
7249
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
7250
|
+
if (expiries.length === 0) {
|
|
7251
|
+
clearTimeout(this.#timer);
|
|
7252
|
+
this.#timer = void 0;
|
|
7253
|
+
return;
|
|
7254
|
+
}
|
|
7255
|
+
if (this.#timer !== void 0) {
|
|
7256
|
+
return;
|
|
7257
|
+
}
|
|
7258
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
7259
|
+
this.#timer = setTimeout(() => {
|
|
7260
|
+
this.#timer = void 0;
|
|
7261
|
+
this.view.dispatch({
|
|
7262
|
+
effects: dequeue.of(Date.now())
|
|
7263
|
+
});
|
|
7264
|
+
}, delay);
|
|
7265
|
+
}
|
|
7266
|
+
destroy() {
|
|
7267
|
+
clearTimeout(this.#timer);
|
|
7268
|
+
}
|
|
7269
|
+
});
|
|
7270
|
+
return [
|
|
7271
|
+
fadeField,
|
|
7272
|
+
cleanup,
|
|
7273
|
+
EditorView29.theme({
|
|
7274
|
+
".cm-fader": {
|
|
7275
|
+
animation: "fader 1s ease-out forwards"
|
|
7276
|
+
},
|
|
7277
|
+
"@keyframes fader": {
|
|
7278
|
+
"0%": {
|
|
7279
|
+
textShadow: "0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)"
|
|
7280
|
+
},
|
|
7281
|
+
"100%": {}
|
|
7282
|
+
}
|
|
7283
|
+
})
|
|
7284
|
+
];
|
|
7285
|
+
};
|
|
7286
|
+
|
|
7287
|
+
// src/extensions/tags/typewriter.ts
|
|
7288
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7289
|
+
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7290
|
+
import { Domino as Domino3 } from "@dxos/ui";
|
|
7291
|
+
var typewriterBypass = Annotation3.define();
|
|
7292
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7293
|
+
var CURSOR_LINGER = 3e3;
|
|
7294
|
+
var FRAME_BUDGET_MS = 4;
|
|
7295
|
+
var CHARS_PER_FRAME = 5;
|
|
7296
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7297
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7298
|
+
var typewriter = (options = {}) => {
|
|
7299
|
+
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7300
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7301
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7302
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7303
|
+
const suppressAppend = StateEffect11.define();
|
|
7304
|
+
const insertChunk = StateEffect11.define();
|
|
7305
|
+
const bufferField = StateField13.define({
|
|
7306
|
+
create: () => ({
|
|
7307
|
+
text: "",
|
|
7308
|
+
head: 0,
|
|
7309
|
+
insertAt: 0
|
|
7310
|
+
}),
|
|
7311
|
+
update: (value, tr) => {
|
|
7312
|
+
let { text, head, insertAt } = value;
|
|
7313
|
+
for (const effect of tr.effects) {
|
|
7314
|
+
if (effect.is(suppressAppend)) {
|
|
7315
|
+
if (text.length === head) {
|
|
7316
|
+
insertAt = effect.value.from;
|
|
7317
|
+
}
|
|
7318
|
+
text += effect.value.text;
|
|
7319
|
+
}
|
|
7320
|
+
if (effect.is(insertChunk)) {
|
|
7321
|
+
head += effect.value.text.length;
|
|
7322
|
+
insertAt = effect.value.from + effect.value.text.length;
|
|
7323
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7324
|
+
text = text.slice(head);
|
|
7325
|
+
head = 0;
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
}
|
|
7329
|
+
if (tr.docChanged) {
|
|
7330
|
+
let isReset = tr.state.doc.length === 0;
|
|
7331
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7332
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7333
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7334
|
+
isReset = true;
|
|
7335
|
+
}
|
|
7336
|
+
});
|
|
7337
|
+
}
|
|
7338
|
+
if (isReset) {
|
|
7339
|
+
return {
|
|
7340
|
+
text: "",
|
|
7341
|
+
head: 0,
|
|
7342
|
+
insertAt: 0
|
|
7343
|
+
};
|
|
7344
|
+
}
|
|
7345
|
+
if (!tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7346
|
+
insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));
|
|
7347
|
+
}
|
|
7348
|
+
}
|
|
7349
|
+
return {
|
|
7350
|
+
text,
|
|
7351
|
+
head,
|
|
7352
|
+
insertAt
|
|
7353
|
+
};
|
|
6989
7354
|
}
|
|
6990
7355
|
});
|
|
6991
|
-
const
|
|
7356
|
+
const filter = EditorState3.transactionFilter.of((tr) => {
|
|
7357
|
+
if (!tr.docChanged) {
|
|
7358
|
+
return tr;
|
|
7359
|
+
}
|
|
7360
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7361
|
+
return tr;
|
|
7362
|
+
}
|
|
7363
|
+
let appendedText = "";
|
|
7364
|
+
let appendFrom = -1;
|
|
7365
|
+
let isAppendOnly = true;
|
|
7366
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {
|
|
7367
|
+
if (toA === tr.startState.doc.length && fromA === toA && inserted.length > 0) {
|
|
7368
|
+
appendedText += inserted.sliceString(0);
|
|
7369
|
+
if (appendFrom === -1) {
|
|
7370
|
+
appendFrom = fromA;
|
|
7371
|
+
}
|
|
7372
|
+
} else {
|
|
7373
|
+
isAppendOnly = false;
|
|
7374
|
+
}
|
|
7375
|
+
});
|
|
7376
|
+
if (!isAppendOnly || appendedText.length === 0) {
|
|
7377
|
+
return tr;
|
|
7378
|
+
}
|
|
7379
|
+
return {
|
|
7380
|
+
changes: ChangeSet2.empty(tr.startState.doc.length),
|
|
7381
|
+
effects: suppressAppend.of({
|
|
7382
|
+
from: appendFrom,
|
|
7383
|
+
text: appendedText
|
|
7384
|
+
})
|
|
7385
|
+
};
|
|
7386
|
+
});
|
|
7387
|
+
const drainPlugin = ViewPlugin21.fromClass(class {
|
|
6992
7388
|
view;
|
|
6993
|
-
|
|
7389
|
+
_raf;
|
|
7390
|
+
_activeStreamTag = null;
|
|
6994
7391
|
constructor(view) {
|
|
6995
7392
|
this.view = view;
|
|
6996
7393
|
}
|
|
6997
7394
|
update(update2) {
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7395
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7396
|
+
const pending = text.length - head;
|
|
7397
|
+
if (pending === 0) {
|
|
7398
|
+
this._activeStreamTag = null;
|
|
7399
|
+
}
|
|
7400
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7401
|
+
this._start();
|
|
7005
7402
|
}
|
|
7006
7403
|
}
|
|
7404
|
+
_start() {
|
|
7405
|
+
queueMicrotask(() => {
|
|
7406
|
+
this.view.dispatch({
|
|
7407
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7408
|
+
annotations: typewriterBypass.of(true)
|
|
7409
|
+
});
|
|
7410
|
+
});
|
|
7411
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7412
|
+
}
|
|
7413
|
+
_tick = () => {
|
|
7414
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7415
|
+
const pending = text.length - head;
|
|
7416
|
+
if (pending === 0) {
|
|
7417
|
+
this.view.dispatch({
|
|
7418
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7419
|
+
annotations: typewriterBypass.of(true)
|
|
7420
|
+
});
|
|
7421
|
+
this._raf = void 0;
|
|
7422
|
+
return;
|
|
7423
|
+
}
|
|
7424
|
+
if (pending > flushThreshold) {
|
|
7425
|
+
const chunk = text.slice(head);
|
|
7426
|
+
this._activeStreamTag = null;
|
|
7427
|
+
this.view.dispatch({
|
|
7428
|
+
changes: {
|
|
7429
|
+
from: insertAt,
|
|
7430
|
+
insert: chunk
|
|
7431
|
+
},
|
|
7432
|
+
effects: insertChunk.of({
|
|
7433
|
+
from: insertAt,
|
|
7434
|
+
text: chunk
|
|
7435
|
+
})
|
|
7436
|
+
});
|
|
7437
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7438
|
+
return;
|
|
7439
|
+
}
|
|
7440
|
+
const startTime = performance.now();
|
|
7441
|
+
let pos = head;
|
|
7442
|
+
let activeTag = this._activeStreamTag;
|
|
7443
|
+
let charsEmitted = 0;
|
|
7444
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7445
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7446
|
+
if (result.count === 0) {
|
|
7447
|
+
break;
|
|
7448
|
+
}
|
|
7449
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7450
|
+
break;
|
|
7451
|
+
}
|
|
7452
|
+
if (result.enterTag) {
|
|
7453
|
+
activeTag = result.enterTag;
|
|
7454
|
+
}
|
|
7455
|
+
if (result.exitTag) {
|
|
7456
|
+
activeTag = null;
|
|
7457
|
+
}
|
|
7458
|
+
pos += result.count;
|
|
7459
|
+
charsEmitted += result.count;
|
|
7460
|
+
}
|
|
7461
|
+
const totalCount = pos - head;
|
|
7462
|
+
if (totalCount > 0) {
|
|
7463
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7464
|
+
this._activeStreamTag = activeTag;
|
|
7465
|
+
this.view.dispatch({
|
|
7466
|
+
changes: {
|
|
7467
|
+
from: insertAt,
|
|
7468
|
+
insert: chunk
|
|
7469
|
+
},
|
|
7470
|
+
effects: insertChunk.of({
|
|
7471
|
+
from: insertAt,
|
|
7472
|
+
text: chunk
|
|
7473
|
+
})
|
|
7474
|
+
});
|
|
7475
|
+
}
|
|
7476
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7477
|
+
};
|
|
7007
7478
|
destroy() {
|
|
7008
|
-
|
|
7479
|
+
if (this._raf !== void 0) {
|
|
7480
|
+
cancelAnimationFrame(this._raf);
|
|
7481
|
+
}
|
|
7009
7482
|
}
|
|
7010
7483
|
});
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7484
|
+
return [
|
|
7485
|
+
bufferField,
|
|
7486
|
+
filter,
|
|
7487
|
+
drainPlugin,
|
|
7488
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7489
|
+
].filter(Boolean);
|
|
7490
|
+
};
|
|
7491
|
+
var typewriterCursor = (bufferField) => {
|
|
7492
|
+
const hideCursor = StateEffect11.define();
|
|
7493
|
+
const visibilityField = StateField13.define({
|
|
7494
|
+
create: () => ({
|
|
7495
|
+
visible: false,
|
|
7496
|
+
insertAt: 0,
|
|
7497
|
+
lastNonWsAt: 0
|
|
7498
|
+
}),
|
|
7499
|
+
update: (value, tr) => {
|
|
7500
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7501
|
+
const pending = text.length - head;
|
|
7502
|
+
if (pending > 0) {
|
|
7503
|
+
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7504
|
+
if (tr.docChanged) {
|
|
7505
|
+
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
7506
|
+
const chunk = inserted.sliceString(0);
|
|
7507
|
+
if (chunk.trim().length > 0) {
|
|
7508
|
+
lastNonWsAt = _fromB + chunk.length;
|
|
7509
|
+
}
|
|
7510
|
+
});
|
|
7511
|
+
}
|
|
7512
|
+
return {
|
|
7513
|
+
visible: true,
|
|
7514
|
+
insertAt,
|
|
7515
|
+
lastNonWsAt
|
|
7516
|
+
};
|
|
7517
|
+
}
|
|
7518
|
+
for (const effect of tr.effects) {
|
|
7519
|
+
if (effect.is(hideCursor)) {
|
|
7520
|
+
return {
|
|
7521
|
+
...value,
|
|
7522
|
+
visible: false
|
|
7523
|
+
};
|
|
7524
|
+
}
|
|
7017
7525
|
}
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7526
|
+
return value;
|
|
7527
|
+
}
|
|
7528
|
+
});
|
|
7529
|
+
const decorationField = StateField13.define({
|
|
7530
|
+
create: () => Decoration15.none,
|
|
7531
|
+
update: (_decorations, tr) => {
|
|
7532
|
+
const { visible, insertAt, lastNonWsAt } = tr.state.field(visibilityField);
|
|
7533
|
+
if (!visible) {
|
|
7534
|
+
return Decoration15.none;
|
|
7535
|
+
}
|
|
7536
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7537
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7538
|
+
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7539
|
+
return Decoration15.set([
|
|
7540
|
+
Decoration15.widget({
|
|
7021
7541
|
widget: new CursorWidget(),
|
|
7022
7542
|
side: 1
|
|
7023
|
-
}).range(
|
|
7543
|
+
}).range(pos)
|
|
7024
7544
|
]);
|
|
7025
7545
|
},
|
|
7026
|
-
provide: (
|
|
7546
|
+
provide: (field) => EditorView30.decorations.from(field)
|
|
7547
|
+
});
|
|
7548
|
+
const timerPlugin = ViewPlugin21.fromClass(class {
|
|
7549
|
+
view;
|
|
7550
|
+
_timer;
|
|
7551
|
+
constructor(view) {
|
|
7552
|
+
this.view = view;
|
|
7553
|
+
}
|
|
7554
|
+
update(update2) {
|
|
7555
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7556
|
+
const { visible } = update2.state.field(visibilityField);
|
|
7557
|
+
const pending = text.length - head;
|
|
7558
|
+
if (pending > 0) {
|
|
7559
|
+
clearTimeout(this._timer);
|
|
7560
|
+
this._timer = void 0;
|
|
7561
|
+
} else if (visible && this._timer === void 0) {
|
|
7562
|
+
this._timer = setTimeout(() => {
|
|
7563
|
+
this.view.dispatch({
|
|
7564
|
+
effects: hideCursor.of(null)
|
|
7565
|
+
});
|
|
7566
|
+
this._timer = void 0;
|
|
7567
|
+
}, CURSOR_LINGER);
|
|
7568
|
+
}
|
|
7569
|
+
}
|
|
7570
|
+
destroy() {
|
|
7571
|
+
clearTimeout(this._timer);
|
|
7572
|
+
}
|
|
7027
7573
|
});
|
|
7028
7574
|
return [
|
|
7029
|
-
|
|
7030
|
-
|
|
7031
|
-
|
|
7575
|
+
visibilityField,
|
|
7576
|
+
decorationField,
|
|
7577
|
+
timerPlugin
|
|
7032
7578
|
];
|
|
7033
7579
|
};
|
|
7034
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7580
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7581
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7582
|
+
// the blink animation isn't restarted on every transaction.
|
|
7583
|
+
eq(other) {
|
|
7584
|
+
return other instanceof _CursorWidget;
|
|
7585
|
+
}
|
|
7035
7586
|
toDOM() {
|
|
7036
|
-
const inner = Domino3.of("span").text("\
|
|
7037
|
-
animation: "blink
|
|
7587
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7588
|
+
animation: "blink 1s infinite",
|
|
7589
|
+
animationDelay: "250ms"
|
|
7038
7590
|
});
|
|
7039
7591
|
return Domino3.of("span").style({
|
|
7040
7592
|
opacity: "0.8"
|
|
7041
|
-
}).
|
|
7593
|
+
}).append(inner).root;
|
|
7042
7594
|
}
|
|
7043
7595
|
};
|
|
7044
|
-
var
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7596
|
+
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7597
|
+
var TAG_NAME_PROBE = 64;
|
|
7598
|
+
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7599
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7600
|
+
if (start >= buffer.length) {
|
|
7601
|
+
return {
|
|
7602
|
+
count: 0
|
|
7603
|
+
};
|
|
7604
|
+
}
|
|
7605
|
+
if (activeStreamTag) {
|
|
7606
|
+
const closeTag = `</${activeStreamTag}>`;
|
|
7607
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7608
|
+
return {
|
|
7609
|
+
count: closeTag.length,
|
|
7610
|
+
exitTag: true
|
|
7611
|
+
};
|
|
7612
|
+
}
|
|
7613
|
+
if (buffer[start] === "<") {
|
|
7614
|
+
return {
|
|
7615
|
+
count: xmlElementLength(buffer, start)
|
|
7616
|
+
};
|
|
7617
|
+
}
|
|
7618
|
+
return {
|
|
7619
|
+
count: 1
|
|
7620
|
+
};
|
|
7621
|
+
}
|
|
7622
|
+
const ch = buffer[start];
|
|
7623
|
+
if (ch === "<") {
|
|
7624
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7625
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7626
|
+
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7627
|
+
const close = buffer.indexOf(">", start);
|
|
7628
|
+
if (close === -1) {
|
|
7629
|
+
return {
|
|
7630
|
+
count: 0
|
|
7631
|
+
};
|
|
7063
7632
|
}
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
isReset = true;
|
|
7069
|
-
}
|
|
7070
|
-
});
|
|
7633
|
+
if (buffer[close - 1] === "/") {
|
|
7634
|
+
return {
|
|
7635
|
+
count: close + 1 - start
|
|
7636
|
+
};
|
|
7071
7637
|
}
|
|
7072
|
-
|
|
7073
|
-
|
|
7638
|
+
return {
|
|
7639
|
+
count: close + 1 - start,
|
|
7640
|
+
enterTag: nameMatch[1]
|
|
7641
|
+
};
|
|
7642
|
+
}
|
|
7643
|
+
return {
|
|
7644
|
+
count: xmlElementLength(buffer, start)
|
|
7645
|
+
};
|
|
7646
|
+
}
|
|
7647
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7648
|
+
return {
|
|
7649
|
+
count: linkLength(buffer, start, start + 1)
|
|
7650
|
+
};
|
|
7651
|
+
}
|
|
7652
|
+
if (ch === "[") {
|
|
7653
|
+
return {
|
|
7654
|
+
count: linkLength(buffer, start, start)
|
|
7655
|
+
};
|
|
7656
|
+
}
|
|
7657
|
+
return {
|
|
7658
|
+
count: 1
|
|
7659
|
+
};
|
|
7660
|
+
};
|
|
7661
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7662
|
+
const close = buffer.indexOf(">", start);
|
|
7663
|
+
if (close === -1) {
|
|
7664
|
+
return 0;
|
|
7665
|
+
}
|
|
7666
|
+
if (buffer[close - 1] === "/") {
|
|
7667
|
+
return close + 1 - start;
|
|
7668
|
+
}
|
|
7669
|
+
if (buffer[start + 1] === "/") {
|
|
7670
|
+
return close + 1 - start;
|
|
7671
|
+
}
|
|
7672
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7673
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7674
|
+
if (!nameMatch) {
|
|
7675
|
+
return 1;
|
|
7676
|
+
}
|
|
7677
|
+
const tagName = nameMatch[1];
|
|
7678
|
+
let depth = 0;
|
|
7679
|
+
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7680
|
+
tagPattern.lastIndex = start;
|
|
7681
|
+
let match;
|
|
7682
|
+
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7683
|
+
const isSelfClosing = match[0].endsWith("/>");
|
|
7684
|
+
const isClosing = match[1] === "/";
|
|
7685
|
+
if (isSelfClosing) {
|
|
7686
|
+
if (depth === 0) {
|
|
7687
|
+
return match.index + match[0].length - start;
|
|
7688
|
+
}
|
|
7689
|
+
} else if (isClosing) {
|
|
7690
|
+
depth--;
|
|
7691
|
+
if (depth === 0) {
|
|
7692
|
+
return match.index + match[0].length - start;
|
|
7074
7693
|
}
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7694
|
+
} else {
|
|
7695
|
+
depth++;
|
|
7696
|
+
}
|
|
7697
|
+
}
|
|
7698
|
+
return 0;
|
|
7699
|
+
};
|
|
7700
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7701
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7702
|
+
if (bracketClose === -1) {
|
|
7703
|
+
return 0;
|
|
7704
|
+
}
|
|
7705
|
+
if (bracketClose + 1 >= buffer.length) {
|
|
7706
|
+
return 0;
|
|
7707
|
+
}
|
|
7708
|
+
if (buffer[bracketClose + 1] !== "(") {
|
|
7709
|
+
return 1;
|
|
7710
|
+
}
|
|
7711
|
+
const parenClose = buffer.indexOf(")", bracketClose + 2);
|
|
7712
|
+
if (parenClose === -1) {
|
|
7713
|
+
return 0;
|
|
7714
|
+
}
|
|
7715
|
+
return parenClose + 1 - start;
|
|
7716
|
+
};
|
|
7717
|
+
|
|
7718
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7719
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7720
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7721
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7722
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7723
|
+
class: lineClass
|
|
7724
|
+
}) : void 0;
|
|
7725
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7726
|
+
class: contentClass
|
|
7727
|
+
}) : void 0;
|
|
7728
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7729
|
+
const buildDecorations5 = (view) => {
|
|
7730
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7731
|
+
if (!text.includes(`<${tag}`)) {
|
|
7732
|
+
return Decoration16.none;
|
|
7733
|
+
}
|
|
7734
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7735
|
+
const ranges = [];
|
|
7736
|
+
tree.iterate({
|
|
7737
|
+
enter: (node) => {
|
|
7738
|
+
if (node.type.name !== "Element") {
|
|
7078
7739
|
return;
|
|
7079
7740
|
}
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7741
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7742
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7743
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7744
|
+
if (!openTag || !tagNameNode) {
|
|
7745
|
+
return;
|
|
7084
7746
|
}
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7747
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7748
|
+
return;
|
|
7749
|
+
}
|
|
7750
|
+
const contentFrom = openTag.to;
|
|
7751
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7752
|
+
if (hideDecoration) {
|
|
7753
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7754
|
+
if (closeTag) {
|
|
7755
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7756
|
+
}
|
|
7757
|
+
}
|
|
7758
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7759
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7760
|
+
}
|
|
7761
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7762
|
+
let pos = contentFrom;
|
|
7763
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7764
|
+
const line = view.state.doc.lineAt(pos);
|
|
7765
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7766
|
+
if (line.to >= contentTo) {
|
|
7767
|
+
break;
|
|
7768
|
+
}
|
|
7769
|
+
pos = line.to + 1;
|
|
7770
|
+
}
|
|
7771
|
+
}
|
|
7772
|
+
}
|
|
7773
|
+
});
|
|
7774
|
+
return Decoration16.set(ranges, true);
|
|
7775
|
+
};
|
|
7776
|
+
return ViewPlugin22.fromClass(class {
|
|
7777
|
+
decorations;
|
|
7096
7778
|
constructor(view) {
|
|
7097
|
-
this.
|
|
7779
|
+
this.decorations = buildDecorations5(view);
|
|
7098
7780
|
}
|
|
7099
7781
|
update(update2) {
|
|
7100
|
-
if (
|
|
7101
|
-
|
|
7782
|
+
if (update2.docChanged) {
|
|
7783
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7102
7784
|
}
|
|
7103
|
-
|
|
7104
|
-
|
|
7785
|
+
}
|
|
7786
|
+
}, {
|
|
7787
|
+
decorations: (instance) => instance.decorations
|
|
7788
|
+
});
|
|
7789
|
+
};
|
|
7790
|
+
|
|
7791
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7792
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7793
|
+
import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
|
|
7794
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7795
|
+
"OpenTag",
|
|
7796
|
+
"CloseTag",
|
|
7797
|
+
"SelfClosingTag",
|
|
7798
|
+
"MismatchedCloseTag"
|
|
7799
|
+
]);
|
|
7800
|
+
var xmlElementMark = Decoration17.mark({
|
|
7801
|
+
class: "cm-xml-element"
|
|
7802
|
+
});
|
|
7803
|
+
var xmlTagMark = Decoration17.mark({
|
|
7804
|
+
class: "cm-xml-tag"
|
|
7805
|
+
});
|
|
7806
|
+
var xmlContentMark = Decoration17.mark({
|
|
7807
|
+
class: "cm-xml-content"
|
|
7808
|
+
});
|
|
7809
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7810
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7811
|
+
const buildDecorations5 = (view) => {
|
|
7812
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7813
|
+
if (!text.includes("<")) {
|
|
7814
|
+
return Decoration17.none;
|
|
7815
|
+
}
|
|
7816
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7817
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7818
|
+
const ranges = [];
|
|
7819
|
+
tree.iterate({
|
|
7820
|
+
enter: (node) => {
|
|
7821
|
+
const name = node.type.name;
|
|
7822
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
7823
|
+
if (skipSet) {
|
|
7824
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
7825
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7826
|
+
return false;
|
|
7827
|
+
}
|
|
7828
|
+
}
|
|
7829
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7830
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7105
7831
|
return;
|
|
7106
7832
|
}
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
7833
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
7834
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7835
|
+
return;
|
|
7836
|
+
}
|
|
7837
|
+
if (name === "Element" && node.from < node.to) {
|
|
7838
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7839
|
+
if (openTag && skipSet) {
|
|
7840
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
7841
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7842
|
+
return false;
|
|
7843
|
+
}
|
|
7844
|
+
}
|
|
7845
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7846
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7847
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
7848
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
7849
|
+
}
|
|
7110
7850
|
}
|
|
7111
|
-
const totalDelay = FADE_IN_DURATION + removalDelay;
|
|
7112
|
-
const id = setTimeout(() => {
|
|
7113
|
-
this.view.dispatch({
|
|
7114
|
-
effects: removeDecoration.of({
|
|
7115
|
-
from: fromB,
|
|
7116
|
-
to: toB
|
|
7117
|
-
})
|
|
7118
|
-
});
|
|
7119
|
-
this._timers.delete(key);
|
|
7120
|
-
}, totalDelay);
|
|
7121
|
-
this._timers.set(key, id);
|
|
7122
|
-
});
|
|
7123
|
-
}
|
|
7124
|
-
destroy() {
|
|
7125
|
-
for (const id of this._timers.values()) {
|
|
7126
|
-
clearTimeout(id);
|
|
7127
7851
|
}
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
}
|
|
7852
|
+
});
|
|
7853
|
+
return Decoration17.set(ranges, true);
|
|
7854
|
+
};
|
|
7131
7855
|
return [
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
},
|
|
7141
|
-
"@keyframes fade-in": {
|
|
7142
|
-
"0%": {
|
|
7143
|
-
opacity: "0"
|
|
7144
|
-
},
|
|
7145
|
-
"80%": {
|
|
7146
|
-
opacity: "1"
|
|
7147
|
-
},
|
|
7148
|
-
"100%": {
|
|
7149
|
-
opacity: "0.8"
|
|
7856
|
+
ViewPlugin23.fromClass(class {
|
|
7857
|
+
decorations;
|
|
7858
|
+
constructor(view) {
|
|
7859
|
+
this.decorations = buildDecorations5(view);
|
|
7860
|
+
}
|
|
7861
|
+
update(update2) {
|
|
7862
|
+
if (update2.docChanged) {
|
|
7863
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7150
7864
|
}
|
|
7151
7865
|
}
|
|
7866
|
+
}, {
|
|
7867
|
+
decorations: (instance) => instance.decorations
|
|
7868
|
+
}),
|
|
7869
|
+
EditorView31.baseTheme({
|
|
7870
|
+
".cm-xml-element": {
|
|
7871
|
+
backgroundColor: "var(--color-active-surface)",
|
|
7872
|
+
borderRadius: "0.25rem",
|
|
7873
|
+
padding: "0.25rem"
|
|
7874
|
+
},
|
|
7875
|
+
".cm-xml-tag": {
|
|
7876
|
+
color: "var(--color-blue-500)",
|
|
7877
|
+
fontFamily: "var(--font-mono)"
|
|
7878
|
+
},
|
|
7879
|
+
".cm-xml-content": {}
|
|
7152
7880
|
})
|
|
7153
7881
|
];
|
|
7154
7882
|
};
|
|
7155
7883
|
|
|
7156
7884
|
// src/extensions/tags/xml-tags.ts
|
|
7157
7885
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7158
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7159
|
-
import { Decoration as
|
|
7886
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
|
|
7887
|
+
import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7160
7888
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7161
7889
|
import { log as log11 } from "@dxos/log";
|
|
7890
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7162
7891
|
|
|
7163
7892
|
// src/extensions/tags/xml-util.ts
|
|
7164
7893
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7165
7894
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7166
7895
|
var nodeToJson = (state, node) => {
|
|
7167
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7168
|
-
F: __dxlog_file16,
|
|
7169
|
-
L: 18,
|
|
7170
|
-
S: void 0,
|
|
7171
|
-
A: [
|
|
7172
|
-
"node.type.name === 'Element'",
|
|
7173
|
-
"'Node is not an Element'"
|
|
7174
|
-
]
|
|
7175
|
-
});
|
|
7896
|
+
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'"] });
|
|
7176
7897
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7177
7898
|
if (openTag) {
|
|
7178
7899
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7204,13 +7925,23 @@ var nodeToJson = (state, node) => {
|
|
|
7204
7925
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7205
7926
|
const children = [];
|
|
7206
7927
|
let child = node.node.firstChild;
|
|
7928
|
+
const appendText = (raw) => {
|
|
7929
|
+
if (raw.length === 0) {
|
|
7930
|
+
return;
|
|
7931
|
+
}
|
|
7932
|
+
const last = children[children.length - 1];
|
|
7933
|
+
if (typeof last === "string") {
|
|
7934
|
+
children[children.length - 1] = last + raw;
|
|
7935
|
+
} else {
|
|
7936
|
+
children.push(raw);
|
|
7937
|
+
}
|
|
7938
|
+
};
|
|
7207
7939
|
while (child) {
|
|
7208
7940
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7209
7941
|
if (child.type.name === "Text") {
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
}
|
|
7942
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
7943
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
7944
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7214
7945
|
} else if (child.type.name === "Element") {
|
|
7215
7946
|
const data = nodeToJson(state, child);
|
|
7216
7947
|
if (data) {
|
|
@@ -7220,26 +7951,63 @@ var nodeToJson = (state, node) => {
|
|
|
7220
7951
|
}
|
|
7221
7952
|
child = child.nextSibling;
|
|
7222
7953
|
}
|
|
7954
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7955
|
+
children[0] = children[0].trimStart();
|
|
7956
|
+
}
|
|
7223
7957
|
if (children.length > 0) {
|
|
7224
|
-
|
|
7958
|
+
const lastIndex = children.length - 1;
|
|
7959
|
+
const last = children[lastIndex];
|
|
7960
|
+
if (typeof last === "string") {
|
|
7961
|
+
children[lastIndex] = last.trimEnd();
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
7965
|
+
if (trimmed.length > 0) {
|
|
7966
|
+
tag.children = trimmed;
|
|
7225
7967
|
}
|
|
7226
7968
|
}
|
|
7227
7969
|
return tag;
|
|
7228
7970
|
}
|
|
7229
7971
|
};
|
|
7972
|
+
var XML_NAMED_ENTITIES = {
|
|
7973
|
+
"<": "<",
|
|
7974
|
+
">": ">",
|
|
7975
|
+
"&": "&",
|
|
7976
|
+
""": '"',
|
|
7977
|
+
"'": "'"
|
|
7978
|
+
};
|
|
7979
|
+
var decodeXmlEntity = (raw) => {
|
|
7980
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
7981
|
+
if (named !== void 0) {
|
|
7982
|
+
return named;
|
|
7983
|
+
}
|
|
7984
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
7985
|
+
if (numeric) {
|
|
7986
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
7987
|
+
if (Number.isFinite(code)) {
|
|
7988
|
+
try {
|
|
7989
|
+
return String.fromCodePoint(code);
|
|
7990
|
+
} catch {
|
|
7991
|
+
}
|
|
7992
|
+
}
|
|
7993
|
+
}
|
|
7994
|
+
return raw;
|
|
7995
|
+
};
|
|
7230
7996
|
|
|
7231
7997
|
// src/extensions/tags/xml-tags.ts
|
|
7232
7998
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
7233
|
-
var navigatePreviousEffect =
|
|
7234
|
-
var navigateNextEffect =
|
|
7999
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8000
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7235
8001
|
var getXmlTextChild = (children) => {
|
|
7236
8002
|
const child = children?.[0];
|
|
7237
8003
|
return typeof child === "string" ? child : null;
|
|
7238
8004
|
};
|
|
7239
|
-
var
|
|
7240
|
-
var
|
|
7241
|
-
var
|
|
7242
|
-
var
|
|
8005
|
+
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
8006
|
+
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8007
|
+
var xmlTagContextEffect = StateEffect12.define();
|
|
8008
|
+
var xmlTagResetEffect = StateEffect12.define();
|
|
8009
|
+
var xmlTagUpdateEffect = StateEffect12.define();
|
|
8010
|
+
var widgetContextStateField = StateField14.define({
|
|
7243
8011
|
create: () => void 0,
|
|
7244
8012
|
update: (value, tr) => {
|
|
7245
8013
|
for (const effect of tr.effects) {
|
|
@@ -7250,7 +8018,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7250
8018
|
return value;
|
|
7251
8019
|
}
|
|
7252
8020
|
});
|
|
7253
|
-
var widgetStateMapStateField =
|
|
8021
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7254
8022
|
create: () => ({}),
|
|
7255
8023
|
update: (map, tr) => {
|
|
7256
8024
|
for (const effect of tr.effects) {
|
|
@@ -7262,12 +8030,7 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7262
8030
|
log11("widget updated", {
|
|
7263
8031
|
id,
|
|
7264
8032
|
value
|
|
7265
|
-
}, {
|
|
7266
|
-
F: __dxlog_file17,
|
|
7267
|
-
L: 153,
|
|
7268
|
-
S: void 0,
|
|
7269
|
-
C: (f, a) => f(...a)
|
|
7270
|
-
});
|
|
8033
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7271
8034
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7272
8035
|
return {
|
|
7273
8036
|
...map,
|
|
@@ -7297,12 +8060,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7297
8060
|
log11("widget mounted", {
|
|
7298
8061
|
id: state.id,
|
|
7299
8062
|
tag: state.props._tag
|
|
7300
|
-
}, {
|
|
7301
|
-
F: __dxlog_file17,
|
|
7302
|
-
L: 206,
|
|
7303
|
-
S: void 0,
|
|
7304
|
-
C: (f, a) => f(...a)
|
|
7305
|
-
});
|
|
8063
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7306
8064
|
widgets.set(state.id, state);
|
|
7307
8065
|
setWidgets?.([
|
|
7308
8066
|
...widgets.values()
|
|
@@ -7313,12 +8071,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7313
8071
|
log11("widget unmounted", {
|
|
7314
8072
|
id,
|
|
7315
8073
|
tag: state?.props._tag
|
|
7316
|
-
}, {
|
|
7317
|
-
F: __dxlog_file17,
|
|
7318
|
-
L: 212,
|
|
7319
|
-
S: void 0,
|
|
7320
|
-
C: (f, a) => f(...a)
|
|
7321
|
-
});
|
|
8074
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7322
8075
|
widgets.delete(id);
|
|
7323
8076
|
setWidgets?.([
|
|
7324
8077
|
...widgets.values()
|
|
@@ -7327,7 +8080,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7327
8080
|
};
|
|
7328
8081
|
return notifier;
|
|
7329
8082
|
};
|
|
7330
|
-
var keyHandlers =
|
|
8083
|
+
var keyHandlers = keymap14.of([
|
|
7331
8084
|
{
|
|
7332
8085
|
key: "Mod-ArrowUp",
|
|
7333
8086
|
run: (view) => {
|
|
@@ -7348,7 +8101,7 @@ var keyHandlers = keymap13.of([
|
|
|
7348
8101
|
}
|
|
7349
8102
|
]);
|
|
7350
8103
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7351
|
-
return
|
|
8104
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7352
8105
|
update2.transactions.forEach((transaction) => {
|
|
7353
8106
|
for (const effect of transaction.effects) {
|
|
7354
8107
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7433,7 +8186,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7433
8186
|
});
|
|
7434
8187
|
});
|
|
7435
8188
|
};
|
|
7436
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8189
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7437
8190
|
update(update2) {
|
|
7438
8191
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7439
8192
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7460,14 +8213,14 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7460
8213
|
}
|
|
7461
8214
|
}
|
|
7462
8215
|
});
|
|
7463
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8216
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7464
8217
|
create: (state) => {
|
|
7465
8218
|
return buildDecorations4(state, {
|
|
7466
8219
|
from: 0,
|
|
7467
8220
|
to: state.doc.length
|
|
7468
8221
|
}, registry, notifier);
|
|
7469
8222
|
},
|
|
7470
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8223
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7471
8224
|
for (const effect of tr.effects) {
|
|
7472
8225
|
if (effect.is(xmlTagResetEffect)) {
|
|
7473
8226
|
if (tr.docChanged) {
|
|
@@ -7478,7 +8231,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7478
8231
|
}
|
|
7479
8232
|
return {
|
|
7480
8233
|
from: 0,
|
|
7481
|
-
decorations:
|
|
8234
|
+
decorations: Decoration18.none
|
|
7482
8235
|
};
|
|
7483
8236
|
}
|
|
7484
8237
|
}
|
|
@@ -7489,24 +8242,23 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7489
8242
|
log11("document reset", {
|
|
7490
8243
|
from,
|
|
7491
8244
|
to: state.doc.length
|
|
7492
|
-
}, {
|
|
7493
|
-
F: __dxlog_file17,
|
|
7494
|
-
L: 374,
|
|
7495
|
-
S: void 0,
|
|
7496
|
-
C: (f, a) => f(...a)
|
|
7497
|
-
});
|
|
8245
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7498
8246
|
return buildDecorations4(state, {
|
|
7499
8247
|
from: 0,
|
|
7500
8248
|
to: state.doc.length
|
|
7501
8249
|
}, registry, notifier);
|
|
7502
8250
|
} else {
|
|
8251
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7503
8252
|
const result = buildDecorations4(state, {
|
|
7504
|
-
from,
|
|
8253
|
+
from: rebuildFrom,
|
|
7505
8254
|
to: state.doc.length
|
|
7506
8255
|
}, registry, notifier);
|
|
7507
8256
|
return {
|
|
7508
8257
|
from: result.from,
|
|
8258
|
+
streamingFrom: result.streamingFrom,
|
|
7509
8259
|
decorations: decorations2.update({
|
|
8260
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8261
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7510
8262
|
add: decorationSetToArray(result.decorations)
|
|
7511
8263
|
})
|
|
7512
8264
|
};
|
|
@@ -7514,12 +8266,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7514
8266
|
}
|
|
7515
8267
|
return {
|
|
7516
8268
|
from,
|
|
8269
|
+
streamingFrom,
|
|
7517
8270
|
decorations: decorations2
|
|
7518
8271
|
};
|
|
7519
8272
|
},
|
|
7520
8273
|
provide: (field) => [
|
|
7521
|
-
|
|
7522
|
-
|
|
8274
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8275
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7523
8276
|
]
|
|
7524
8277
|
});
|
|
7525
8278
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7530,10 +8283,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7530
8283
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7531
8284
|
return {
|
|
7532
8285
|
from: range.from,
|
|
7533
|
-
decorations:
|
|
8286
|
+
decorations: Decoration18.none
|
|
7534
8287
|
};
|
|
7535
8288
|
}
|
|
7536
8289
|
let last = range.from;
|
|
8290
|
+
let streamingFrom;
|
|
7537
8291
|
tree.iterate({
|
|
7538
8292
|
from: range.from,
|
|
7539
8293
|
to: range.to,
|
|
@@ -7546,21 +8300,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7546
8300
|
if (args) {
|
|
7547
8301
|
const def = registry[args._tag];
|
|
7548
8302
|
if (def) {
|
|
8303
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8304
|
+
return false;
|
|
8305
|
+
}
|
|
7549
8306
|
const { block, factory, Component } = def;
|
|
7550
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7551
8307
|
const nodeRange = {
|
|
7552
8308
|
from: node.node.from,
|
|
7553
8309
|
to: node.node.to
|
|
7554
8310
|
};
|
|
8311
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8312
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7555
8313
|
const props = {
|
|
7556
|
-
|
|
8314
|
+
id: widgetId,
|
|
7557
8315
|
range: nodeRange,
|
|
8316
|
+
context,
|
|
7558
8317
|
...args,
|
|
7559
8318
|
...widgetState
|
|
7560
8319
|
};
|
|
7561
|
-
const widget = factory ? factory(props) : Component ?
|
|
8320
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7562
8321
|
if (widget) {
|
|
7563
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8322
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7564
8323
|
widget,
|
|
7565
8324
|
block,
|
|
7566
8325
|
atomic: true,
|
|
@@ -7572,20 +8331,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7572
8331
|
}
|
|
7573
8332
|
}
|
|
7574
8333
|
} catch (err) {
|
|
7575
|
-
log11.catch(err, void 0, {
|
|
7576
|
-
F: __dxlog_file17,
|
|
7577
|
-
L: 459,
|
|
7578
|
-
S: void 0,
|
|
7579
|
-
C: (f, a) => f(...a)
|
|
7580
|
-
});
|
|
8334
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7581
8335
|
}
|
|
7582
8336
|
return false;
|
|
7583
8337
|
}
|
|
7584
8338
|
}
|
|
7585
8339
|
}
|
|
7586
8340
|
});
|
|
8341
|
+
const streamingTagNames = Object.entries(registry).filter(([, def]) => def.streaming).map(([name]) => name).sort((a, b) => b.length - a.length);
|
|
8342
|
+
if (streamingTagNames.length > 0) {
|
|
8343
|
+
const tailText = state.sliceDoc(range.from, range.to);
|
|
8344
|
+
const streamingPattern = streamingTagNames.map(escapeRegExpSource3).join("|");
|
|
8345
|
+
const tagPattern = new RegExp(`<(${streamingPattern})(\\s[^>]*)?>`, "g");
|
|
8346
|
+
let match;
|
|
8347
|
+
while ((match = tagPattern.exec(tailText)) !== null) {
|
|
8348
|
+
const tagName = match[1];
|
|
8349
|
+
const closeTag = `</${tagName}>`;
|
|
8350
|
+
const afterOpen = match.index + match[0].length;
|
|
8351
|
+
if (tailText.indexOf(closeTag, afterOpen) === -1) {
|
|
8352
|
+
const absoluteFrom = range.from + match.index;
|
|
8353
|
+
const contentFrom = range.from + afterOpen;
|
|
8354
|
+
const innerText = state.sliceDoc(contentFrom, range.to).trim();
|
|
8355
|
+
const def = registry[tagName];
|
|
8356
|
+
const props = {
|
|
8357
|
+
_tag: tagName,
|
|
8358
|
+
context,
|
|
8359
|
+
range: {
|
|
8360
|
+
from: absoluteFrom,
|
|
8361
|
+
to: range.to
|
|
8362
|
+
},
|
|
8363
|
+
children: innerText ? [
|
|
8364
|
+
innerText
|
|
8365
|
+
] : void 0
|
|
8366
|
+
};
|
|
8367
|
+
const attrPattern = /(\w+)="([^"]*)"/g;
|
|
8368
|
+
let attrMatch;
|
|
8369
|
+
while ((attrMatch = attrPattern.exec(match[0])) !== null) {
|
|
8370
|
+
props[attrMatch[1]] = attrMatch[2];
|
|
8371
|
+
}
|
|
8372
|
+
const widgetId = xmlWidgetId(props.id, `cm-xml-${absoluteFrom}`);
|
|
8373
|
+
const widgetState = widgetStateMap[widgetId];
|
|
8374
|
+
const mergedProps = {
|
|
8375
|
+
...props,
|
|
8376
|
+
id: widgetId,
|
|
8377
|
+
...widgetState
|
|
8378
|
+
};
|
|
8379
|
+
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8380
|
+
if (widget) {
|
|
8381
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8382
|
+
widget,
|
|
8383
|
+
block: def.block,
|
|
8384
|
+
atomic: true,
|
|
8385
|
+
inclusive: true,
|
|
8386
|
+
tag: tagName,
|
|
8387
|
+
streaming: true,
|
|
8388
|
+
contentFrom
|
|
8389
|
+
}));
|
|
8390
|
+
streamingFrom = absoluteFrom;
|
|
8391
|
+
last = absoluteFrom;
|
|
8392
|
+
}
|
|
8393
|
+
break;
|
|
8394
|
+
}
|
|
8395
|
+
}
|
|
8396
|
+
}
|
|
7587
8397
|
return {
|
|
7588
8398
|
from: last,
|
|
8399
|
+
streamingFrom,
|
|
7589
8400
|
decorations: builder.finish()
|
|
7590
8401
|
};
|
|
7591
8402
|
};
|
|
@@ -7594,108 +8405,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7594
8405
|
Component;
|
|
7595
8406
|
props;
|
|
7596
8407
|
notifier;
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
S: this,
|
|
7604
|
-
A: [
|
|
7605
|
-
"id",
|
|
7606
|
-
""
|
|
7607
|
-
]
|
|
7608
|
-
});
|
|
8408
|
+
streaming;
|
|
8409
|
+
#root = null;
|
|
8410
|
+
#view;
|
|
8411
|
+
constructor(id, Component, props, notifier, streaming) {
|
|
8412
|
+
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8413
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
7609
8414
|
}
|
|
7610
8415
|
get root() {
|
|
7611
|
-
return this
|
|
8416
|
+
return this.#root;
|
|
7612
8417
|
}
|
|
7613
8418
|
eq(other) {
|
|
8419
|
+
if (this.streaming) {
|
|
8420
|
+
return false;
|
|
8421
|
+
}
|
|
7614
8422
|
return this.id === other.id;
|
|
7615
8423
|
}
|
|
7616
8424
|
ignoreEvent() {
|
|
7617
8425
|
return true;
|
|
7618
8426
|
}
|
|
7619
|
-
toDOM(
|
|
7620
|
-
this
|
|
8427
|
+
toDOM(view) {
|
|
8428
|
+
this.#view = view;
|
|
8429
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8430
|
+
const props = Object.assign({}, this.props, {
|
|
8431
|
+
view
|
|
8432
|
+
});
|
|
8433
|
+
this.notifier.mounted({
|
|
8434
|
+
id: this.id,
|
|
8435
|
+
root: this.#root,
|
|
8436
|
+
props,
|
|
8437
|
+
Component: this.Component
|
|
8438
|
+
});
|
|
8439
|
+
return this.#root;
|
|
8440
|
+
}
|
|
8441
|
+
updateDOM(dom) {
|
|
8442
|
+
this.#root = dom;
|
|
8443
|
+
const props = Object.assign({}, this.props, {
|
|
8444
|
+
view: this.#view
|
|
8445
|
+
});
|
|
7621
8446
|
this.notifier.mounted({
|
|
7622
8447
|
id: this.id,
|
|
7623
|
-
root: this
|
|
7624
|
-
props
|
|
8448
|
+
root: this.#root,
|
|
8449
|
+
props,
|
|
7625
8450
|
Component: this.Component
|
|
7626
8451
|
});
|
|
7627
|
-
return
|
|
8452
|
+
return true;
|
|
7628
8453
|
}
|
|
7629
8454
|
destroy(_dom) {
|
|
7630
8455
|
this.notifier.unmounted(this.id);
|
|
7631
|
-
this
|
|
8456
|
+
this.#root = null;
|
|
8457
|
+
this.#view = void 0;
|
|
7632
8458
|
}
|
|
7633
8459
|
};
|
|
7634
|
-
|
|
7635
|
-
// src/extensions/typewriter.ts
|
|
7636
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
7637
|
-
var defaultItems = [
|
|
7638
|
-
"hello world!",
|
|
7639
|
-
"this is a test.",
|
|
7640
|
-
"this is [DXOS](https://dxos.org)"
|
|
7641
|
-
];
|
|
7642
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7643
|
-
let t;
|
|
7644
|
-
let idx = 0;
|
|
7645
|
-
return [
|
|
7646
|
-
keymap14.of([
|
|
7647
|
-
{
|
|
7648
|
-
// Reset.
|
|
7649
|
-
key: "alt-meta-'",
|
|
7650
|
-
run: () => {
|
|
7651
|
-
clearTimeout(t);
|
|
7652
|
-
idx = 0;
|
|
7653
|
-
return true;
|
|
7654
|
-
}
|
|
7655
|
-
},
|
|
7656
|
-
{
|
|
7657
|
-
// Next prompt.
|
|
7658
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
7659
|
-
key: "Shift-Meta-'",
|
|
7660
|
-
run: (view) => {
|
|
7661
|
-
clearTimeout(t);
|
|
7662
|
-
const text = items[idx++];
|
|
7663
|
-
if (idx === items?.length) {
|
|
7664
|
-
idx = 0;
|
|
7665
|
-
}
|
|
7666
|
-
let i = 0;
|
|
7667
|
-
const insert = (d = 0) => {
|
|
7668
|
-
t = setTimeout(() => {
|
|
7669
|
-
const pos = view.state.selection.main.head;
|
|
7670
|
-
view.dispatch({
|
|
7671
|
-
changes: {
|
|
7672
|
-
from: pos,
|
|
7673
|
-
insert: text[i++]
|
|
7674
|
-
},
|
|
7675
|
-
selection: {
|
|
7676
|
-
anchor: pos + 1
|
|
7677
|
-
}
|
|
7678
|
-
});
|
|
7679
|
-
if (i < text.length) {
|
|
7680
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
7681
|
-
}
|
|
7682
|
-
}, d);
|
|
7683
|
-
};
|
|
7684
|
-
insert();
|
|
7685
|
-
return true;
|
|
7686
|
-
}
|
|
7687
|
-
}
|
|
7688
|
-
])
|
|
7689
|
-
];
|
|
7690
|
-
};
|
|
7691
8460
|
export {
|
|
7692
8461
|
Cursor,
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
EditorState3 as EditorState,
|
|
7696
|
-
EditorView30 as EditorView,
|
|
7697
|
-
EditorViewMode,
|
|
7698
|
-
EditorViewModes,
|
|
8462
|
+
EditorState4 as EditorState,
|
|
8463
|
+
EditorView33 as EditorView,
|
|
7699
8464
|
Inline,
|
|
7700
8465
|
InputModeExtensions,
|
|
7701
8466
|
List,
|
|
@@ -7712,6 +8477,7 @@ export {
|
|
|
7712
8477
|
addStyle,
|
|
7713
8478
|
annotations,
|
|
7714
8479
|
autoScroll,
|
|
8480
|
+
autoScrollEffect,
|
|
7715
8481
|
autocomplete,
|
|
7716
8482
|
automerge,
|
|
7717
8483
|
awareness,
|
|
@@ -7725,6 +8491,7 @@ export {
|
|
|
7725
8491
|
commentClickedEffect,
|
|
7726
8492
|
comments,
|
|
7727
8493
|
commentsState,
|
|
8494
|
+
compactSlots,
|
|
7728
8495
|
convertTreeToJson,
|
|
7729
8496
|
createBasicExtensions,
|
|
7730
8497
|
createComment,
|
|
@@ -7748,12 +8515,12 @@ export {
|
|
|
7748
8515
|
defaultThemeSlots,
|
|
7749
8516
|
deleteItem,
|
|
7750
8517
|
documentId,
|
|
8518
|
+
documentSlots,
|
|
7751
8519
|
dropFile,
|
|
8520
|
+
editorClassNames,
|
|
7752
8521
|
editorInputMode,
|
|
7753
|
-
editorSlots,
|
|
7754
|
-
editorWidth,
|
|
7755
|
-
editorWithToolbarLayout,
|
|
7756
8522
|
extendedMarkdown,
|
|
8523
|
+
fader,
|
|
7757
8524
|
filterChars,
|
|
7758
8525
|
flattenRect,
|
|
7759
8526
|
focus,
|
|
@@ -7789,6 +8556,7 @@ export {
|
|
|
7789
8556
|
markdownTagsExtensions,
|
|
7790
8557
|
matchCompletion,
|
|
7791
8558
|
mention,
|
|
8559
|
+
mobileSlots,
|
|
7792
8560
|
modalStateEffect,
|
|
7793
8561
|
modalStateField,
|
|
7794
8562
|
moveItemDown,
|
|
@@ -7808,6 +8576,7 @@ export {
|
|
|
7808
8576
|
removeList,
|
|
7809
8577
|
removeStyle,
|
|
7810
8578
|
replacer,
|
|
8579
|
+
scrollPastEnd,
|
|
7811
8580
|
scrollThreadIntoView,
|
|
7812
8581
|
scrollToLine,
|
|
7813
8582
|
scroller,
|
|
@@ -7820,9 +8589,8 @@ export {
|
|
|
7820
8589
|
setSelection,
|
|
7821
8590
|
setStyle,
|
|
7822
8591
|
singleValueFacet,
|
|
7823
|
-
|
|
8592
|
+
snippets2 as snippets,
|
|
7824
8593
|
staticCompletion,
|
|
7825
|
-
streamer,
|
|
7826
8594
|
submit,
|
|
7827
8595
|
tabbable,
|
|
7828
8596
|
table,
|
|
@@ -7841,7 +8609,12 @@ export {
|
|
|
7841
8609
|
treeFacet,
|
|
7842
8610
|
typeahead,
|
|
7843
8611
|
typewriter,
|
|
8612
|
+
typewriterBypass,
|
|
8613
|
+
typewriterDrainingEffect,
|
|
7844
8614
|
wrapWithCatch,
|
|
8615
|
+
xmlBlockDecoration,
|
|
8616
|
+
xmlElementLength,
|
|
8617
|
+
xmlFormatting,
|
|
7845
8618
|
xmlTagContextEffect,
|
|
7846
8619
|
xmlTagResetEffect,
|
|
7847
8620
|
xmlTagUpdateEffect,
|