@dxos/ui-editor 0.8.4-main.c85a9c8dae → 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 +1530 -752
- 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 +1531 -752
- 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 -20
- package/src/extensions/auto-scroll.ts +115 -9
- package/src/extensions/automerge/automerge.test.tsx +35 -9
- package/src/extensions/automerge/automerge.ts +5 -7
- 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 +48 -24
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +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,29 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EditorInputMode,
|
|
3
|
-
EditorInputModes,
|
|
4
|
-
EditorViewMode,
|
|
5
|
-
EditorViewModes
|
|
6
|
-
} from "./chunk-HL3YF6WC.mjs";
|
|
7
|
-
|
|
8
1
|
// src/index.ts
|
|
9
|
-
import { EditorState as
|
|
10
|
-
import { EditorView as
|
|
2
|
+
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
3
|
+
import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
|
|
11
4
|
import { tags as tags2 } from "@lezer/highlight";
|
|
12
5
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
13
6
|
|
|
14
7
|
// src/defaults.ts
|
|
15
8
|
import { mx } from "@dxos/ui-theme";
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
var editorClassNames = (role) => mx("dx-attention-surface p-0.5 data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
10
|
+
var documentSlots = {
|
|
11
|
+
content: {
|
|
12
|
+
/**
|
|
13
|
+
* CodeMirror content width.
|
|
14
|
+
* 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
|
|
15
|
+
* 50rem = 800px. Maximum content width for solo mode.
|
|
16
|
+
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
17
|
+
*/
|
|
18
|
+
className: mx(
|
|
19
|
+
// Inline-size container for widget sizing (children use `max-w-[100cqi]`).
|
|
20
|
+
// NOTE: Use inline-size, not full size containment — `container-type: size` on the
|
|
21
|
+
// editor content breaks CodeMirror's viewport measurement, leaving blank gaps during
|
|
22
|
+
// scroll until a click forces a re-measure.
|
|
23
|
+
"dx-inline-size-container",
|
|
24
|
+
// Wider margin for web (vs. mobile).
|
|
25
|
+
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
26
|
+
"mx-auto! w-full"
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var compactSlots = {
|
|
31
|
+
content: {
|
|
32
|
+
className: "mx-2!"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var mobileSlots = {
|
|
21
36
|
content: {
|
|
22
|
-
className:
|
|
37
|
+
className: "mx-2!"
|
|
23
38
|
}
|
|
24
39
|
};
|
|
25
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
26
|
-
var stackItemContentEditorClassNames = (role) => mx("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");
|
|
27
40
|
|
|
28
41
|
// src/extensions/annotations.ts
|
|
29
42
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
@@ -207,7 +220,7 @@ var singleValueFacet = (defaultValue) => Facet.define({
|
|
|
207
220
|
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
208
221
|
var defaultCursorConverter = {
|
|
209
222
|
toCursor: (position) => position.toString(),
|
|
210
|
-
fromCursor: (
|
|
223
|
+
fromCursor: (cursor) => parseInt(cursor)
|
|
211
224
|
};
|
|
212
225
|
var Cursor = class _Cursor {
|
|
213
226
|
static converter = singleValueFacet(defaultCursorConverter);
|
|
@@ -220,9 +233,9 @@ var Cursor = class _Cursor {
|
|
|
220
233
|
to
|
|
221
234
|
].join(":");
|
|
222
235
|
};
|
|
223
|
-
static getRangeFromCursor = (state,
|
|
236
|
+
static getRangeFromCursor = (state, cursor) => {
|
|
224
237
|
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
225
|
-
const parts =
|
|
238
|
+
const parts = cursor.split(":");
|
|
226
239
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
227
240
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
228
241
|
return from !== void 0 && to !== void 0 ? {
|
|
@@ -258,12 +271,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
258
271
|
} catch (err) {
|
|
259
272
|
log.catch(err, {
|
|
260
273
|
label
|
|
261
|
-
}, {
|
|
262
|
-
F: __dxlog_file,
|
|
263
|
-
L: 20,
|
|
264
|
-
S: void 0,
|
|
265
|
-
C: (f, a) => f(...a)
|
|
266
|
-
});
|
|
274
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
267
275
|
}
|
|
268
276
|
};
|
|
269
277
|
};
|
|
@@ -289,12 +297,7 @@ var logChanges = (trs) => {
|
|
|
289
297
|
if (changes.length) {
|
|
290
298
|
log("changes", {
|
|
291
299
|
changes
|
|
292
|
-
}, {
|
|
293
|
-
F: __dxlog_file,
|
|
294
|
-
L: 54,
|
|
295
|
-
S: void 0,
|
|
296
|
-
C: (f, a) => f(...a)
|
|
297
|
-
});
|
|
300
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
298
301
|
}
|
|
299
302
|
};
|
|
300
303
|
|
|
@@ -502,9 +505,11 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
502
505
|
};
|
|
503
506
|
|
|
504
507
|
// src/extensions/auto-scroll.ts
|
|
508
|
+
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
505
509
|
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
506
510
|
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
507
511
|
import { Domino } from "@dxos/ui";
|
|
512
|
+
import { getSize } from "@dxos/ui-theme";
|
|
508
513
|
|
|
509
514
|
// src/extensions/scroller.ts
|
|
510
515
|
import { StateEffect } from "@codemirror/state";
|
|
@@ -561,8 +566,7 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
561
566
|
}
|
|
562
567
|
requestAnimationFrame(() => {
|
|
563
568
|
this.view.scrollDOM.scrollTo({
|
|
564
|
-
top: targetScrollTop
|
|
565
|
-
behavior
|
|
569
|
+
top: targetScrollTop
|
|
566
570
|
});
|
|
567
571
|
});
|
|
568
572
|
}
|
|
@@ -584,23 +588,19 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
584
588
|
}
|
|
585
589
|
}
|
|
586
590
|
} catch (err) {
|
|
587
|
-
log2.catch(err, void 0, {
|
|
588
|
-
F: __dxlog_file2,
|
|
589
|
-
L: 145,
|
|
590
|
-
S: void 0,
|
|
591
|
-
C: (f, a) => f(...a)
|
|
592
|
-
});
|
|
591
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
|
|
593
592
|
}
|
|
594
593
|
});
|
|
595
594
|
}),
|
|
596
595
|
// Styles.
|
|
597
596
|
EditorView4.theme({
|
|
598
|
-
".cm-content": {
|
|
599
|
-
paddingBottom: `${overScroll}px`
|
|
600
|
-
},
|
|
601
597
|
".cm-scroller": {
|
|
602
|
-
|
|
603
|
-
|
|
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"
|
|
604
604
|
},
|
|
605
605
|
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
606
606
|
display: "none"
|
|
@@ -612,6 +612,16 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
612
612
|
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
613
613
|
background: "var(--color-scrollbar-thumb)"
|
|
614
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
|
+
},
|
|
615
625
|
".cm-scroll-button": {
|
|
616
626
|
position: "absolute",
|
|
617
627
|
bottom: "0.5rem",
|
|
@@ -620,22 +630,28 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
620
630
|
})
|
|
621
631
|
];
|
|
622
632
|
};
|
|
623
|
-
function createCrawler(view,
|
|
633
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
624
634
|
const el = view.scrollDOM;
|
|
625
635
|
let currentTop = 0;
|
|
636
|
+
let velocity = 0;
|
|
626
637
|
let rafId = null;
|
|
627
|
-
|
|
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;
|
|
628
642
|
const targetTop = el.scrollHeight - el.clientHeight;
|
|
629
643
|
const delta = targetTop - currentTop;
|
|
630
|
-
|
|
631
|
-
if (absDelta < targetDelta) {
|
|
644
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
632
645
|
el.scrollTop = targetTop;
|
|
633
646
|
currentTop = targetTop;
|
|
647
|
+
velocity = 0;
|
|
634
648
|
rafId = null;
|
|
649
|
+
lastTime = 0;
|
|
635
650
|
return;
|
|
636
651
|
}
|
|
637
|
-
const
|
|
638
|
-
|
|
652
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
653
|
+
velocity += accel * dt;
|
|
654
|
+
currentTop += velocity * dt;
|
|
639
655
|
el.scrollTop = currentTop;
|
|
640
656
|
rafId = requestAnimationFrame(frame);
|
|
641
657
|
}
|
|
@@ -643,12 +659,15 @@ function createCrawler(view, k = 0.3, maxStep = 2, targetDelta = 0.5) {
|
|
|
643
659
|
scroll: () => {
|
|
644
660
|
if (rafId === null) {
|
|
645
661
|
currentTop = el.scrollTop;
|
|
662
|
+
lastTime = 0;
|
|
646
663
|
rafId = requestAnimationFrame(frame);
|
|
647
664
|
}
|
|
648
665
|
},
|
|
649
666
|
cancel: () => {
|
|
650
667
|
if (rafId !== null) {
|
|
651
668
|
cancelAnimationFrame(rafId);
|
|
669
|
+
velocity = 0;
|
|
670
|
+
lastTime = 0;
|
|
652
671
|
rafId = null;
|
|
653
672
|
}
|
|
654
673
|
}
|
|
@@ -656,26 +675,64 @@ function createCrawler(view, k = 0.3, maxStep = 2, targetDelta = 0.5) {
|
|
|
656
675
|
}
|
|
657
676
|
|
|
658
677
|
// src/extensions/auto-scroll.ts
|
|
659
|
-
var
|
|
678
|
+
var autoScrollEffect = StateEffect2.define();
|
|
679
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
660
680
|
let buttonContainer;
|
|
661
681
|
let isPinned = true;
|
|
682
|
+
let jumpPending = false;
|
|
683
|
+
let enabled = true;
|
|
684
|
+
let firstUpdate = true;
|
|
662
685
|
const setPinned = (pinned) => {
|
|
663
686
|
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
664
687
|
isPinned = pinned;
|
|
665
688
|
};
|
|
666
689
|
return [
|
|
667
|
-
// Update listener for
|
|
668
|
-
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
|
+
}
|
|
669
726
|
if (heightChanged) {
|
|
670
727
|
if (isPinned) {
|
|
671
728
|
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
672
729
|
const delta = scrollHeight - scrollTop - clientHeight;
|
|
673
|
-
if (delta > 0
|
|
730
|
+
if (delta > 0) {
|
|
674
731
|
setPinned(true);
|
|
675
732
|
view.dispatch({
|
|
676
733
|
effects: scrollerCrawlEffect.of(true)
|
|
677
734
|
});
|
|
678
|
-
} else if (delta <
|
|
735
|
+
} else if (delta < -1) {
|
|
679
736
|
setPinned(false);
|
|
680
737
|
}
|
|
681
738
|
} else {
|
|
@@ -685,6 +742,43 @@ var autoScroll = (_ = {}) => {
|
|
|
685
742
|
}
|
|
686
743
|
}
|
|
687
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
|
+
}) : [],
|
|
688
782
|
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
689
783
|
ViewPlugin6.fromClass(class {
|
|
690
784
|
cleanup;
|
|
@@ -710,12 +804,12 @@ var autoScroll = (_ = {}) => {
|
|
|
710
804
|
// Scroll button.
|
|
711
805
|
ViewPlugin6.fromClass(class {
|
|
712
806
|
constructor(view) {
|
|
713
|
-
const icon = Domino.of("dx-icon").attributes({
|
|
807
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
714
808
|
icon: "ph--arrow-down--regular"
|
|
715
809
|
});
|
|
716
810
|
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
717
811
|
"data-density": "fine"
|
|
718
|
-
}).
|
|
812
|
+
}).append(icon).on("click", () => {
|
|
719
813
|
setPinned(true);
|
|
720
814
|
view.dispatch({
|
|
721
815
|
effects: scrollerLineEffect.of({
|
|
@@ -725,7 +819,7 @@ var autoScroll = (_ = {}) => {
|
|
|
725
819
|
})
|
|
726
820
|
});
|
|
727
821
|
});
|
|
728
|
-
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;
|
|
729
823
|
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
730
824
|
}
|
|
731
825
|
})
|
|
@@ -760,35 +854,25 @@ var cursorConverter = (accessor) => ({
|
|
|
760
854
|
try {
|
|
761
855
|
return toCursor(accessor, pos, assoc);
|
|
762
856
|
} catch (err) {
|
|
763
|
-
log3.catch(err, void 0, {
|
|
764
|
-
F: __dxlog_file3,
|
|
765
|
-
L: 15,
|
|
766
|
-
S: void 0,
|
|
767
|
-
C: (f, a) => f(...a)
|
|
768
|
-
});
|
|
857
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 11, S: void 0 });
|
|
769
858
|
return "";
|
|
770
859
|
}
|
|
771
860
|
},
|
|
772
|
-
fromCursor: (
|
|
861
|
+
fromCursor: (cursor) => {
|
|
773
862
|
try {
|
|
774
|
-
return fromCursor(accessor,
|
|
863
|
+
return fromCursor(accessor, cursor);
|
|
775
864
|
} catch (err) {
|
|
776
|
-
log3.catch(err, void 0, {
|
|
777
|
-
F: __dxlog_file3,
|
|
778
|
-
L: 24,
|
|
779
|
-
S: void 0,
|
|
780
|
-
C: (f, a) => f(...a)
|
|
781
|
-
});
|
|
865
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 19, S: void 0 });
|
|
782
866
|
return 0;
|
|
783
867
|
}
|
|
784
868
|
}
|
|
785
869
|
});
|
|
786
870
|
|
|
787
871
|
// src/extensions/automerge/defs.ts
|
|
788
|
-
import { Annotation, StateEffect as
|
|
872
|
+
import { Annotation, StateEffect as StateEffect3 } from "@codemirror/state";
|
|
789
873
|
var getPath = (state, field) => state.field(field).path;
|
|
790
874
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
791
|
-
var updateHeadsEffect =
|
|
875
|
+
var updateHeadsEffect = StateEffect3.define({});
|
|
792
876
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
793
877
|
newHeads
|
|
794
878
|
});
|
|
@@ -963,12 +1047,7 @@ var Syncer = class {
|
|
|
963
1047
|
this._pending = false;
|
|
964
1048
|
}
|
|
965
1049
|
onEditorChange(view) {
|
|
966
|
-
log4("onEditorChange", void 0, {
|
|
967
|
-
F: __dxlog_file4,
|
|
968
|
-
L: 45,
|
|
969
|
-
S: this,
|
|
970
|
-
C: (f, a) => f(...a)
|
|
971
|
-
});
|
|
1050
|
+
log4("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 35, S: this });
|
|
972
1051
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
973
1052
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
974
1053
|
if (newHeads) {
|
|
@@ -979,12 +1058,7 @@ var Syncer = class {
|
|
|
979
1058
|
}
|
|
980
1059
|
}
|
|
981
1060
|
onAutomergeChange(view) {
|
|
982
|
-
log4("onAutomergeChange", void 0, {
|
|
983
|
-
F: __dxlog_file4,
|
|
984
|
-
L: 60,
|
|
985
|
-
S: this,
|
|
986
|
-
C: (f, a) => f(...a)
|
|
987
|
-
});
|
|
1061
|
+
log4("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 47, S: this });
|
|
988
1062
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
989
1063
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
990
1064
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1046,6 +1120,17 @@ var automerge = (accessor) => {
|
|
|
1046
1120
|
const value = DocAccessor.getValue(accessor);
|
|
1047
1121
|
const current = this._view.state.doc.toString();
|
|
1048
1122
|
if (value !== current) {
|
|
1123
|
+
this._view.dispatch({
|
|
1124
|
+
changes: {
|
|
1125
|
+
from: 0,
|
|
1126
|
+
to: this._view.state.doc.length,
|
|
1127
|
+
insert: value
|
|
1128
|
+
},
|
|
1129
|
+
annotations: [
|
|
1130
|
+
initialSync,
|
|
1131
|
+
reconcileAnnotation.of(true)
|
|
1132
|
+
]
|
|
1133
|
+
});
|
|
1049
1134
|
}
|
|
1050
1135
|
});
|
|
1051
1136
|
}
|
|
@@ -1096,10 +1181,7 @@ var awareness = (provider = dummyProvider) => {
|
|
|
1096
1181
|
];
|
|
1097
1182
|
};
|
|
1098
1183
|
var RemoteSelectionsDecorator = class {
|
|
1099
|
-
_ctx = new Context(void 0, {
|
|
1100
|
-
F: __dxlog_file5,
|
|
1101
|
-
L: 80
|
|
1102
|
-
});
|
|
1184
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
|
|
1103
1185
|
_cursorConverter;
|
|
1104
1186
|
_provider;
|
|
1105
1187
|
_lastAnchor;
|
|
@@ -1330,10 +1412,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1330
1412
|
this._info = info;
|
|
1331
1413
|
}
|
|
1332
1414
|
open() {
|
|
1333
|
-
this._ctx = new Context2(void 0, {
|
|
1334
|
-
F: __dxlog_file6,
|
|
1335
|
-
L: 57
|
|
1336
|
-
});
|
|
1415
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
|
|
1337
1416
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1338
1417
|
if (this._localState) {
|
|
1339
1418
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1360,12 +1439,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1360
1439
|
}).catch((err) => {
|
|
1361
1440
|
log5.debug("failed to query awareness", {
|
|
1362
1441
|
err
|
|
1363
|
-
}, {
|
|
1364
|
-
F: __dxlog_file6,
|
|
1365
|
-
L: 91,
|
|
1366
|
-
S: this,
|
|
1367
|
-
C: (f, a) => f(...a)
|
|
1368
|
-
});
|
|
1442
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
|
|
1369
1443
|
});
|
|
1370
1444
|
}
|
|
1371
1445
|
close() {
|
|
@@ -1377,15 +1451,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1377
1451
|
return Array.from(this._remoteStates.values());
|
|
1378
1452
|
}
|
|
1379
1453
|
update(position) {
|
|
1380
|
-
invariant(this._postTask, void 0, {
|
|
1381
|
-
F: __dxlog_file6,
|
|
1382
|
-
L: 106,
|
|
1383
|
-
S: this,
|
|
1384
|
-
A: [
|
|
1385
|
-
"this._postTask",
|
|
1386
|
-
""
|
|
1387
|
-
]
|
|
1388
|
-
});
|
|
1454
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1389
1455
|
this._localState = {
|
|
1390
1456
|
peerId: this._peerId,
|
|
1391
1457
|
position,
|
|
@@ -1394,27 +1460,11 @@ var SpaceAwarenessProvider = class {
|
|
|
1394
1460
|
this._postTask.schedule();
|
|
1395
1461
|
}
|
|
1396
1462
|
_handleQueryMessage() {
|
|
1397
|
-
invariant(this._postTask, void 0, {
|
|
1398
|
-
F: __dxlog_file6,
|
|
1399
|
-
L: 117,
|
|
1400
|
-
S: this,
|
|
1401
|
-
A: [
|
|
1402
|
-
"this._postTask",
|
|
1403
|
-
""
|
|
1404
|
-
]
|
|
1405
|
-
});
|
|
1463
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1406
1464
|
this._postTask.schedule();
|
|
1407
1465
|
}
|
|
1408
1466
|
_handlePostMessage(message) {
|
|
1409
|
-
invariant(message.kind === "post", void 0, {
|
|
1410
|
-
F: __dxlog_file6,
|
|
1411
|
-
L: 122,
|
|
1412
|
-
S: this,
|
|
1413
|
-
A: [
|
|
1414
|
-
"message.kind === 'post'",
|
|
1415
|
-
""
|
|
1416
|
-
]
|
|
1417
|
-
});
|
|
1467
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1418
1468
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1419
1469
|
this.remoteStateChange.emit();
|
|
1420
1470
|
}
|
|
@@ -1543,15 +1593,7 @@ var Blaster = class {
|
|
|
1543
1593
|
return this._node;
|
|
1544
1594
|
}
|
|
1545
1595
|
initialize() {
|
|
1546
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1547
|
-
F: __dxlog_file7,
|
|
1548
|
-
L: 142,
|
|
1549
|
-
S: this,
|
|
1550
|
-
A: [
|
|
1551
|
-
"!this._canvas && !this._ctx",
|
|
1552
|
-
""
|
|
1553
|
-
]
|
|
1554
|
-
});
|
|
1596
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1555
1597
|
this._canvas = document.createElement("canvas");
|
|
1556
1598
|
this._canvas.id = "code-blast-canvas";
|
|
1557
1599
|
this._canvas.style.position = "absolute";
|
|
@@ -1580,15 +1622,7 @@ var Blaster = class {
|
|
|
1580
1622
|
}
|
|
1581
1623
|
}
|
|
1582
1624
|
start() {
|
|
1583
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1584
|
-
F: __dxlog_file7,
|
|
1585
|
-
L: 181,
|
|
1586
|
-
S: this,
|
|
1587
|
-
A: [
|
|
1588
|
-
"this._canvas && this._ctx",
|
|
1589
|
-
""
|
|
1590
|
-
]
|
|
1591
|
-
});
|
|
1625
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1592
1626
|
this._running = true;
|
|
1593
1627
|
this.loop();
|
|
1594
1628
|
}
|
|
@@ -1823,13 +1857,13 @@ var blocks = () => [
|
|
|
1823
1857
|
];
|
|
1824
1858
|
|
|
1825
1859
|
// src/extensions/bookmarks.ts
|
|
1826
|
-
import { Prec as Prec3, StateEffect as
|
|
1860
|
+
import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
|
|
1827
1861
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1828
1862
|
import { log as log6 } from "@dxos/log";
|
|
1829
1863
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1830
|
-
var addBookmark =
|
|
1831
|
-
var removeBookmark =
|
|
1832
|
-
var clearBookmarks =
|
|
1864
|
+
var addBookmark = StateEffect4.define();
|
|
1865
|
+
var removeBookmark = StateEffect4.define();
|
|
1866
|
+
var clearBookmarks = StateEffect4.define();
|
|
1833
1867
|
var bookmarks = () => {
|
|
1834
1868
|
return [
|
|
1835
1869
|
bookmarksField,
|
|
@@ -1838,12 +1872,7 @@ var bookmarks = () => {
|
|
|
1838
1872
|
key: "Mod-ArrowUp",
|
|
1839
1873
|
run: (view) => {
|
|
1840
1874
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1841
|
-
log6("up", bookmarks2, {
|
|
1842
|
-
F: __dxlog_file8,
|
|
1843
|
-
L: 29,
|
|
1844
|
-
S: void 0,
|
|
1845
|
-
C: (f, a) => f(...a)
|
|
1846
|
-
});
|
|
1875
|
+
log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
|
|
1847
1876
|
return true;
|
|
1848
1877
|
}
|
|
1849
1878
|
},
|
|
@@ -1851,12 +1880,7 @@ var bookmarks = () => {
|
|
|
1851
1880
|
key: "Mod-ArrowDown",
|
|
1852
1881
|
run: (view) => {
|
|
1853
1882
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1854
|
-
log6("down", bookmarks2, {
|
|
1855
|
-
F: __dxlog_file8,
|
|
1856
|
-
L: 37,
|
|
1857
|
-
S: void 0,
|
|
1858
|
-
C: (f, a) => f(...a)
|
|
1859
|
-
});
|
|
1883
|
+
log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
|
|
1860
1884
|
return true;
|
|
1861
1885
|
}
|
|
1862
1886
|
}
|
|
@@ -1893,7 +1917,7 @@ var bookmarksField = StateField2.define({
|
|
|
1893
1917
|
|
|
1894
1918
|
// src/extensions/comments.ts
|
|
1895
1919
|
import { invertedEffects } from "@codemirror/commands";
|
|
1896
|
-
import { StateEffect as
|
|
1920
|
+
import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
|
|
1897
1921
|
import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1898
1922
|
import sortBy from "lodash.sortby";
|
|
1899
1923
|
import { debounce as debounce2 } from "@dxos/async";
|
|
@@ -1908,7 +1932,7 @@ import { invariant as invariant3 } from "@dxos/invariant";
|
|
|
1908
1932
|
import { isTruthy } from "@dxos/util";
|
|
1909
1933
|
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1910
1934
|
var documentId = singleValueFacet();
|
|
1911
|
-
var stateRestoreAnnotation = "dxos.
|
|
1935
|
+
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1912
1936
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1913
1937
|
return {
|
|
1914
1938
|
selection,
|
|
@@ -1921,28 +1945,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1921
1945
|
};
|
|
1922
1946
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1923
1947
|
getState: (id) => {
|
|
1924
|
-
invariant3(id, void 0, {
|
|
1925
|
-
F: __dxlog_file9,
|
|
1926
|
-
L: 47,
|
|
1927
|
-
S: void 0,
|
|
1928
|
-
A: [
|
|
1929
|
-
"id",
|
|
1930
|
-
""
|
|
1931
|
-
]
|
|
1932
|
-
});
|
|
1948
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
|
|
1933
1949
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1934
1950
|
return state ? JSON.parse(state) : void 0;
|
|
1935
1951
|
},
|
|
1936
1952
|
setState: (id, state) => {
|
|
1937
|
-
invariant3(id, void 0, {
|
|
1938
|
-
F: __dxlog_file9,
|
|
1939
|
-
L: 53,
|
|
1940
|
-
S: void 0,
|
|
1941
|
-
A: [
|
|
1942
|
-
"id",
|
|
1943
|
-
""
|
|
1944
|
-
]
|
|
1945
|
-
});
|
|
1953
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
|
|
1946
1954
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1947
1955
|
}
|
|
1948
1956
|
});
|
|
@@ -1995,9 +2003,9 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
1995
2003
|
|
|
1996
2004
|
// src/extensions/comments.ts
|
|
1997
2005
|
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1998
|
-
var setComments =
|
|
1999
|
-
var setSelection =
|
|
2000
|
-
var setCommentState =
|
|
2006
|
+
var setComments = StateEffect5.define();
|
|
2007
|
+
var setSelection = StateEffect5.define();
|
|
2008
|
+
var setCommentState = StateEffect5.define();
|
|
2001
2009
|
var commentsState = StateField3.define({
|
|
2002
2010
|
create: (state) => ({
|
|
2003
2011
|
id: state.facet(documentId),
|
|
@@ -2064,12 +2072,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2064
2072
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2065
2073
|
const range = comment.range;
|
|
2066
2074
|
if (!range) {
|
|
2067
|
-
log7.warn("Invalid range:", range, {
|
|
2068
|
-
F: __dxlog_file10,
|
|
2069
|
-
L: 140,
|
|
2070
|
-
S: void 0,
|
|
2071
|
-
C: (f, a) => f(...a)
|
|
2072
|
-
});
|
|
2075
|
+
log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
|
|
2073
2076
|
return void 0;
|
|
2074
2077
|
} else if (range.from === range.to) {
|
|
2075
2078
|
return void 0;
|
|
@@ -2079,7 +2082,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2079
2082
|
}).filter(isNonNullable);
|
|
2080
2083
|
return Decoration7.set(decorations2);
|
|
2081
2084
|
});
|
|
2082
|
-
var commentClickedEffect =
|
|
2085
|
+
var commentClickedEffect = StateEffect5.define();
|
|
2083
2086
|
var handleCommentClick = EditorView11.domEventHandlers({
|
|
2084
2087
|
click: (event, view) => {
|
|
2085
2088
|
let target = event.target;
|
|
@@ -2182,10 +2185,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2182
2185
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2183
2186
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2184
2187
|
if (!exists) {
|
|
2185
|
-
const
|
|
2188
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2186
2189
|
onUpdate({
|
|
2187
2190
|
id: comment.id,
|
|
2188
|
-
cursor
|
|
2191
|
+
cursor
|
|
2189
2192
|
});
|
|
2190
2193
|
}
|
|
2191
2194
|
}
|
|
@@ -2197,7 +2200,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2197
2200
|
from: changes.mapPos(comment.from, 1),
|
|
2198
2201
|
to: changes.mapPos(comment.to, 1)
|
|
2199
2202
|
});
|
|
2200
|
-
var restoreCommentEffect =
|
|
2203
|
+
var restoreCommentEffect = StateEffect5.define({
|
|
2201
2204
|
map: mapTrackedComment
|
|
2202
2205
|
});
|
|
2203
2206
|
var createComment = (view) => {
|
|
@@ -2214,13 +2217,13 @@ var createComment = (view) => {
|
|
|
2214
2217
|
}
|
|
2215
2218
|
});
|
|
2216
2219
|
}
|
|
2217
|
-
const
|
|
2220
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2218
2221
|
from,
|
|
2219
2222
|
to
|
|
2220
2223
|
});
|
|
2221
|
-
if (
|
|
2224
|
+
if (cursor) {
|
|
2222
2225
|
options.onCreate?.({
|
|
2223
|
-
cursor
|
|
2226
|
+
cursor,
|
|
2224
2227
|
from,
|
|
2225
2228
|
location: view.coordsAtPos(from)
|
|
2226
2229
|
});
|
|
@@ -2461,7 +2464,7 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2461
2464
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2462
2465
|
import { searchKeymap } from "@codemirror/search";
|
|
2463
2466
|
import { EditorState } from "@codemirror/state";
|
|
2464
|
-
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";
|
|
2465
2468
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2466
2469
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2467
2470
|
import { generateName } from "@dxos/display-name";
|
|
@@ -2473,28 +2476,28 @@ import { EditorView as EditorView13 } from "@codemirror/view";
|
|
|
2473
2476
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2474
2477
|
var headings = {
|
|
2475
2478
|
1: {
|
|
2476
|
-
className: "text-
|
|
2477
|
-
fontSize: "var(--text-
|
|
2479
|
+
className: "text-3xl",
|
|
2480
|
+
fontSize: "var(--text-3xl)",
|
|
2478
2481
|
lineHeight: "var(--text-4xl--line-height)"
|
|
2479
2482
|
},
|
|
2480
2483
|
2: {
|
|
2481
|
-
className: "text-
|
|
2482
|
-
fontSize: "var(--text-
|
|
2484
|
+
className: "text-2xl",
|
|
2485
|
+
fontSize: "var(--text-2xl)",
|
|
2483
2486
|
lineHeight: "var(--text-3xl--line-height)"
|
|
2484
2487
|
},
|
|
2485
2488
|
3: {
|
|
2486
|
-
className: "text-
|
|
2487
|
-
fontSize: "var(--text-
|
|
2489
|
+
className: "text-xl",
|
|
2490
|
+
fontSize: "var(--text-xl)",
|
|
2488
2491
|
lineHeight: "var(--text-2xl--line-height)"
|
|
2489
2492
|
},
|
|
2490
2493
|
4: {
|
|
2491
|
-
className: "text-
|
|
2492
|
-
fontSize: "var(--text-
|
|
2494
|
+
className: "text-lg",
|
|
2495
|
+
fontSize: "var(--text-lg)",
|
|
2493
2496
|
lineHeight: "var(--text-xl--line-height)"
|
|
2494
2497
|
},
|
|
2495
2498
|
5: {
|
|
2496
|
-
className: "text-
|
|
2497
|
-
fontSize: "var(--text-
|
|
2499
|
+
className: "text-base",
|
|
2500
|
+
fontSize: "var(--text-base)",
|
|
2498
2501
|
lineHeight: "var(--text-lg--line-height)"
|
|
2499
2502
|
},
|
|
2500
2503
|
6: {
|
|
@@ -2503,20 +2506,20 @@ var headings = {
|
|
|
2503
2506
|
lineHeight: "var(--text-base--line-height)"
|
|
2504
2507
|
}
|
|
2505
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';
|
|
2506
2511
|
var markdownTheme = {
|
|
2507
|
-
code: "font-mono
|
|
2508
|
-
codeMark: "font-mono
|
|
2509
|
-
mark: "
|
|
2512
|
+
code: "font-mono! cm-code-inline",
|
|
2513
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2514
|
+
mark: "font-mono!",
|
|
2510
2515
|
heading: (level) => ({
|
|
2511
|
-
className: mx3(headings[level].className, "font-light text-cm-heading"),
|
|
2516
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2512
2517
|
color: "var(--color-cm-heading) !important",
|
|
2513
2518
|
lineHeight: headings[level].lineHeight,
|
|
2514
2519
|
fontSize: headings[level].fontSize,
|
|
2515
2520
|
fontWeight: "100 !important"
|
|
2516
2521
|
})
|
|
2517
2522
|
};
|
|
2518
|
-
var fontBody = "Inter Variable, ui-sans-serif, system-ui, sans-serif";
|
|
2519
|
-
var fontMono = "JetBrains Mono Variable, ui-monospace, Cascadia Code, Source Code Pro, monospace";
|
|
2520
2523
|
var baseTheme = EditorView13.baseTheme({
|
|
2521
2524
|
/**
|
|
2522
2525
|
* Outer frame.
|
|
@@ -2529,12 +2532,21 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2529
2532
|
* Scroller
|
|
2530
2533
|
*/
|
|
2531
2534
|
".cm-scroller": {
|
|
2532
|
-
|
|
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"
|
|
2533
2539
|
},
|
|
2534
2540
|
".cm-scroller::-webkit-scrollbar": {
|
|
2535
|
-
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"
|
|
2536
2549
|
},
|
|
2537
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2538
2550
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2539
2551
|
background: "transparent",
|
|
2540
2552
|
transition: "background 0.15s"
|
|
@@ -2548,7 +2560,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2548
2560
|
*/
|
|
2549
2561
|
".cm-content": {
|
|
2550
2562
|
padding: "unset",
|
|
2551
|
-
lineHeight: "24px",
|
|
2552
2563
|
color: "unset"
|
|
2553
2564
|
},
|
|
2554
2565
|
/**
|
|
@@ -2579,9 +2590,16 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2579
2590
|
* Line.
|
|
2580
2591
|
*/
|
|
2581
2592
|
".cm-line": {
|
|
2582
|
-
lineHeight:
|
|
2593
|
+
lineHeight: 1.5,
|
|
2583
2594
|
paddingInline: 0
|
|
2584
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
|
+
},
|
|
2585
2603
|
".cm-activeLine": {
|
|
2586
2604
|
background: "var(--color-cm-active-line)"
|
|
2587
2605
|
},
|
|
@@ -2759,10 +2777,9 @@ var editorGutter = EditorView13.theme({
|
|
|
2759
2777
|
}
|
|
2760
2778
|
});
|
|
2761
2779
|
var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
2762
|
-
//
|
|
2780
|
+
// Main content.
|
|
2763
2781
|
".cm-scroller": {
|
|
2764
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2765
|
-
fontSize: "16px"
|
|
2782
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2766
2783
|
},
|
|
2767
2784
|
// Maintain defaults for UI components.
|
|
2768
2785
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2772,9 +2789,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2772
2789
|
});
|
|
2773
2790
|
|
|
2774
2791
|
// src/extensions/focus.ts
|
|
2775
|
-
import { StateEffect as
|
|
2792
|
+
import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
|
|
2776
2793
|
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
2777
|
-
var focusEffect =
|
|
2794
|
+
var focusEffect = StateEffect6.define();
|
|
2778
2795
|
var focusField = StateField5.define({
|
|
2779
2796
|
create: () => false,
|
|
2780
2797
|
update: (value, tr) => {
|
|
@@ -2802,9 +2819,32 @@ var focus = [
|
|
|
2802
2819
|
})
|
|
2803
2820
|
];
|
|
2804
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
|
+
|
|
2805
2845
|
// src/extensions/factories.ts
|
|
2806
2846
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2807
|
-
var tabbable =
|
|
2847
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2808
2848
|
tabindex: "0"
|
|
2809
2849
|
});
|
|
2810
2850
|
var filterChars = (chars) => {
|
|
@@ -2857,13 +2897,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2857
2897
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2858
2898
|
return [
|
|
2859
2899
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2860
|
-
|
|
2861
|
-
log8.catch(err, void 0, {
|
|
2862
|
-
F: __dxlog_file11,
|
|
2863
|
-
L: 131,
|
|
2864
|
-
S: void 0,
|
|
2865
|
-
C: (f, a) => f(...a)
|
|
2866
|
-
});
|
|
2900
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2901
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2867
2902
|
}),
|
|
2868
2903
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2869
2904
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2872,7 +2907,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2872
2907
|
props.drawSelection && drawSelection({
|
|
2873
2908
|
cursorBlinkRate: 1200
|
|
2874
2909
|
}),
|
|
2875
|
-
props.editable !== void 0 &&
|
|
2910
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2876
2911
|
props.focus && focus,
|
|
2877
2912
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2878
2913
|
props.history && history(),
|
|
@@ -2880,9 +2915,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2880
2915
|
lineNumbers(),
|
|
2881
2916
|
editorGutter
|
|
2882
2917
|
],
|
|
2883
|
-
props.lineWrapping &&
|
|
2918
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2884
2919
|
props.placeholder && placeholder2(props.placeholder),
|
|
2885
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),
|
|
2886
2928
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2887
2929
|
props.tabbable && tabbable,
|
|
2888
2930
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2925,24 +2967,29 @@ var defaultStyles = {
|
|
|
2925
2967
|
dark: vscodeDarkStyle,
|
|
2926
2968
|
light: vscodeLightStyle
|
|
2927
2969
|
};
|
|
2928
|
-
var createThemeExtensions = ({ monospace,
|
|
2970
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2929
2971
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2930
2972
|
return [
|
|
2931
2973
|
baseTheme,
|
|
2932
|
-
|
|
2974
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2933
2975
|
createFontTheme({
|
|
2934
2976
|
monospace
|
|
2935
2977
|
}),
|
|
2936
2978
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2937
|
-
slots.editor?.className &&
|
|
2979
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2938
2980
|
class: slots.editor.className
|
|
2939
2981
|
}),
|
|
2940
|
-
slots.content?.className &&
|
|
2982
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2941
2983
|
class: slots.content.className
|
|
2942
2984
|
}),
|
|
2943
|
-
slots.
|
|
2985
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2944
2986
|
constructor(view) {
|
|
2945
|
-
|
|
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
|
+
}
|
|
2946
2993
|
}
|
|
2947
2994
|
})
|
|
2948
2995
|
].filter(isTruthy2);
|
|
@@ -2971,7 +3018,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2971
3018
|
|
|
2972
3019
|
// src/extensions/folding.ts
|
|
2973
3020
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2974
|
-
import { EditorView as
|
|
3021
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2975
3022
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2976
3023
|
var folding = () => {
|
|
2977
3024
|
return [
|
|
@@ -2979,13 +3026,14 @@ var folding = () => {
|
|
|
2979
3026
|
placeholderDOM: () => Domino2.of("span").root
|
|
2980
3027
|
}),
|
|
2981
3028
|
foldGutter({
|
|
3029
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2982
3030
|
markerDOM: (open) => {
|
|
2983
|
-
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({
|
|
2984
3032
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2985
3033
|
}))).root;
|
|
2986
3034
|
}
|
|
2987
3035
|
}),
|
|
2988
|
-
|
|
3036
|
+
EditorView17.theme({
|
|
2989
3037
|
".cm-foldGutter": {
|
|
2990
3038
|
opacity: 0.3,
|
|
2991
3039
|
transition: "opacity 0.3s",
|
|
@@ -2999,7 +3047,7 @@ var folding = () => {
|
|
|
2999
3047
|
};
|
|
3000
3048
|
|
|
3001
3049
|
// src/extensions/hashtag.ts
|
|
3002
|
-
import { Decoration as Decoration8, EditorView as
|
|
3050
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3003
3051
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
3004
3052
|
var TagWidget = class extends WidgetType4 {
|
|
3005
3053
|
_text;
|
|
@@ -3020,7 +3068,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3020
3068
|
})
|
|
3021
3069
|
});
|
|
3022
3070
|
var hashtag = () => [
|
|
3023
|
-
|
|
3071
|
+
ViewPlugin13.fromClass(class {
|
|
3024
3072
|
tags;
|
|
3025
3073
|
constructor(view) {
|
|
3026
3074
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3030,11 +3078,11 @@ var hashtag = () => [
|
|
|
3030
3078
|
}
|
|
3031
3079
|
}, {
|
|
3032
3080
|
decorations: (instance) => instance.tags,
|
|
3033
|
-
provide: (plugin) =>
|
|
3081
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
3034
3082
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3035
3083
|
})
|
|
3036
3084
|
}),
|
|
3037
|
-
|
|
3085
|
+
EditorView18.theme({
|
|
3038
3086
|
".cm-tag": {
|
|
3039
3087
|
borderRadius: "4px",
|
|
3040
3088
|
marginRight: "6px",
|
|
@@ -3089,18 +3137,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3089
3137
|
};
|
|
3090
3138
|
|
|
3091
3139
|
// src/extensions/listener.ts
|
|
3092
|
-
import { EditorView as
|
|
3140
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3093
3141
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3094
3142
|
var listener = ({ onFocus, onChange }) => {
|
|
3095
3143
|
return [
|
|
3096
|
-
onFocus &&
|
|
3144
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3097
3145
|
onFocus({
|
|
3098
3146
|
id: state.facet(documentId),
|
|
3099
3147
|
focusing
|
|
3100
3148
|
});
|
|
3101
3149
|
return null;
|
|
3102
3150
|
}),
|
|
3103
|
-
onChange &&
|
|
3151
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3104
3152
|
if (docChanged) {
|
|
3105
3153
|
onChange({
|
|
3106
3154
|
id: state.facet(documentId),
|
|
@@ -3115,7 +3163,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3115
3163
|
import { snippet } from "@codemirror/autocomplete";
|
|
3116
3164
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3117
3165
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3118
|
-
import { EditorView as
|
|
3166
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3119
3167
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3120
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;
|
|
3121
3169
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4204,7 +4252,7 @@ var getFormatting = (state) => {
|
|
|
4204
4252
|
};
|
|
4205
4253
|
};
|
|
4206
4254
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4207
|
-
return
|
|
4255
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4208
4256
|
if (update2.docChanged || update2.selectionSet) {
|
|
4209
4257
|
onStateChange(getFormatting(update2.state));
|
|
4210
4258
|
}
|
|
@@ -4265,8 +4313,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4265
4313
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4266
4314
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4267
4315
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4268
|
-
import {
|
|
4269
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4316
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4270
4317
|
import { languages } from "@codemirror/language-data";
|
|
4271
4318
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4272
4319
|
import { isTruthy as isTruthy3 } from "@dxos/util";
|
|
@@ -4276,11 +4323,6 @@ import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
|
4276
4323
|
import { HighlightStyle as HighlightStyle2 } from "@codemirror/language";
|
|
4277
4324
|
import { Tag, styleTags, tags } from "@lezer/highlight";
|
|
4278
4325
|
import { Table } from "@lezer/markdown";
|
|
4279
|
-
var styles4 = {
|
|
4280
|
-
code: "font-mono no-underline! text-cm-code",
|
|
4281
|
-
codeMark: "font-mono text-cm-code-mark",
|
|
4282
|
-
mark: "opacity-50"
|
|
4283
|
-
};
|
|
4284
4326
|
var markdownTags = {
|
|
4285
4327
|
Blockquote: Tag.define(),
|
|
4286
4328
|
CodeMark: Tag.define(),
|
|
@@ -4362,7 +4404,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4362
4404
|
markdownTags.LinkReference,
|
|
4363
4405
|
markdownTags.ListMark
|
|
4364
4406
|
],
|
|
4365
|
-
class:
|
|
4407
|
+
class: markdownTheme.mark
|
|
4366
4408
|
},
|
|
4367
4409
|
// Markdown marks.
|
|
4368
4410
|
{
|
|
@@ -4373,7 +4415,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4373
4415
|
markdownTags.QuoteMark,
|
|
4374
4416
|
markdownTags.EmphasisMark
|
|
4375
4417
|
],
|
|
4376
|
-
class:
|
|
4418
|
+
class: markdownTheme.mark
|
|
4377
4419
|
},
|
|
4378
4420
|
// E.g., code block language (after ```).
|
|
4379
4421
|
{
|
|
@@ -4382,7 +4424,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4382
4424
|
tags.function(tags.variableName),
|
|
4383
4425
|
tags.labelName
|
|
4384
4426
|
],
|
|
4385
|
-
class:
|
|
4427
|
+
class: markdownTheme.codeMark
|
|
4386
4428
|
},
|
|
4387
4429
|
// Fonts.
|
|
4388
4430
|
{
|
|
@@ -4448,7 +4490,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4448
4490
|
markdownTags.CodeText,
|
|
4449
4491
|
markdownTags.InlineCode
|
|
4450
4492
|
],
|
|
4451
|
-
class:
|
|
4493
|
+
class: markdownTheme.code
|
|
4452
4494
|
},
|
|
4453
4495
|
{
|
|
4454
4496
|
tag: [
|
|
@@ -4478,15 +4520,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4478
4520
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4479
4521
|
base: markdownLanguage2,
|
|
4480
4522
|
// Languages for syntax highlighting fenced code blocks.
|
|
4523
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4481
4524
|
defaultCodeLanguage: jsonLanguage,
|
|
4482
|
-
codeLanguages:
|
|
4525
|
+
codeLanguages: [
|
|
4526
|
+
...options.codeLanguages ?? [],
|
|
4527
|
+
...languages
|
|
4528
|
+
],
|
|
4483
4529
|
// Don't complete HTML tags.
|
|
4484
4530
|
completeHTMLTags: false,
|
|
4485
4531
|
// Parser extensions.
|
|
4486
4532
|
extensions: [
|
|
4487
4533
|
// GFM provided by default.
|
|
4488
4534
|
markdownTagsExtensions,
|
|
4489
|
-
...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
|
|
4490
4540
|
]
|
|
4491
4541
|
}),
|
|
4492
4542
|
// Custom styles.
|
|
@@ -4501,18 +4551,13 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4501
4551
|
].filter(isTruthy3))
|
|
4502
4552
|
];
|
|
4503
4553
|
};
|
|
4504
|
-
var
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
]
|
|
4510
|
-
|
|
4511
|
-
"xml",
|
|
4512
|
-
"xhtml"
|
|
4513
|
-
],
|
|
4514
|
-
load: async () => xml()
|
|
4515
|
-
});
|
|
4554
|
+
var noFencedCodeFolding = {
|
|
4555
|
+
props: [
|
|
4556
|
+
foldNodeProp.add({
|
|
4557
|
+
FencedCode: () => null
|
|
4558
|
+
})
|
|
4559
|
+
]
|
|
4560
|
+
};
|
|
4516
4561
|
var defaultExtensions = () => [
|
|
4517
4562
|
noSetExtHeading,
|
|
4518
4563
|
noHtml
|
|
@@ -4532,19 +4577,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4532
4577
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4533
4578
|
});
|
|
4534
4579
|
var convertTreeToJson = (state) => {
|
|
4535
|
-
const treeToJson = (
|
|
4580
|
+
const treeToJson = (cursor) => {
|
|
4536
4581
|
const node = {
|
|
4537
|
-
type:
|
|
4538
|
-
from:
|
|
4539
|
-
to:
|
|
4540
|
-
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(),
|
|
4541
4586
|
children: []
|
|
4542
4587
|
};
|
|
4543
|
-
if (
|
|
4588
|
+
if (cursor.firstChild()) {
|
|
4544
4589
|
do {
|
|
4545
|
-
node.children.push(treeToJson(
|
|
4546
|
-
} while (
|
|
4547
|
-
|
|
4590
|
+
node.children.push(treeToJson(cursor));
|
|
4591
|
+
} while (cursor.nextSibling());
|
|
4592
|
+
cursor.parent();
|
|
4548
4593
|
}
|
|
4549
4594
|
return node;
|
|
4550
4595
|
};
|
|
@@ -4553,17 +4598,16 @@ var convertTreeToJson = (state) => {
|
|
|
4553
4598
|
|
|
4554
4599
|
// src/extensions/markdown/decorate.ts
|
|
4555
4600
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4556
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4557
|
-
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";
|
|
4558
4603
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4559
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4560
4604
|
|
|
4561
4605
|
// src/extensions/markdown/changes.ts
|
|
4562
4606
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4563
4607
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4564
|
-
import { ViewPlugin as
|
|
4608
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4565
4609
|
var adjustChanges = () => {
|
|
4566
|
-
return
|
|
4610
|
+
return ViewPlugin14.fromClass(class {
|
|
4567
4611
|
update(update2) {
|
|
4568
4612
|
const tree = syntaxTree4(update2.state);
|
|
4569
4613
|
const adjustments = [];
|
|
@@ -4705,7 +4749,7 @@ var getValidUrl = (str) => {
|
|
|
4705
4749
|
// src/extensions/markdown/image.ts
|
|
4706
4750
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4707
4751
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4708
|
-
import { Decoration as Decoration9, EditorView as
|
|
4752
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4709
4753
|
var image = (_options = {}) => {
|
|
4710
4754
|
return [
|
|
4711
4755
|
StateField7.define({
|
|
@@ -4716,10 +4760,10 @@ var image = (_options = {}) => {
|
|
|
4716
4760
|
if (!tr.docChanged && !tr.selection) {
|
|
4717
4761
|
return value;
|
|
4718
4762
|
}
|
|
4719
|
-
const
|
|
4763
|
+
const cursor = tr.state.selection.main.head;
|
|
4720
4764
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4721
|
-
let from = Math.min(
|
|
4722
|
-
let to = Math.max(
|
|
4765
|
+
let from = Math.min(cursor, oldCursor);
|
|
4766
|
+
let to = Math.max(cursor, oldCursor);
|
|
4723
4767
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4724
4768
|
from = Math.min(from, fromB);
|
|
4725
4769
|
to = Math.max(to, toB);
|
|
@@ -4733,19 +4777,19 @@ var image = (_options = {}) => {
|
|
|
4733
4777
|
add: buildDecorations(tr.state, from, to)
|
|
4734
4778
|
});
|
|
4735
4779
|
},
|
|
4736
|
-
provide: (field) =>
|
|
4780
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4737
4781
|
})
|
|
4738
4782
|
];
|
|
4739
4783
|
};
|
|
4740
4784
|
var buildDecorations = (state, from, to) => {
|
|
4741
4785
|
const decorations2 = [];
|
|
4742
|
-
const
|
|
4786
|
+
const cursor = state.selection.main.head;
|
|
4743
4787
|
syntaxTree5(state).iterate({
|
|
4744
4788
|
enter: (node) => {
|
|
4745
4789
|
if (node.name === "Image") {
|
|
4746
4790
|
const urlNode = node.node.getChild("URL");
|
|
4747
4791
|
if (urlNode) {
|
|
4748
|
-
const hide2 = state.readOnly ||
|
|
4792
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4749
4793
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4750
4794
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4751
4795
|
return;
|
|
@@ -4793,10 +4837,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4793
4837
|
};
|
|
4794
4838
|
|
|
4795
4839
|
// src/extensions/markdown/styles.ts
|
|
4796
|
-
import { EditorView as
|
|
4840
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4797
4841
|
var bulletListIndentationWidth = 24;
|
|
4798
4842
|
var orderedListIndentationWidth = 36;
|
|
4799
|
-
var formattingStyles =
|
|
4843
|
+
var formattingStyles = EditorView22.theme({
|
|
4800
4844
|
/**
|
|
4801
4845
|
* Horizontal rule.
|
|
4802
4846
|
*/
|
|
@@ -4831,13 +4875,38 @@ var formattingStyles = EditorView21.theme({
|
|
|
4831
4875
|
background: "var(--color-cm-codeblock)",
|
|
4832
4876
|
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4833
4877
|
paddingLeft: "1rem",
|
|
4834
|
-
margin:
|
|
4878
|
+
margin: 0
|
|
4835
4879
|
},
|
|
4836
4880
|
/**
|
|
4837
4881
|
* Code and codeblocks.
|
|
4838
4882
|
*/
|
|
4883
|
+
"& code": {
|
|
4884
|
+
fontFamily: fontMono,
|
|
4885
|
+
color: "var(--color-cm-code)",
|
|
4886
|
+
whiteSpace: "nowrap"
|
|
4887
|
+
},
|
|
4839
4888
|
"& .cm-code": {
|
|
4840
|
-
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"
|
|
4841
4910
|
},
|
|
4842
4911
|
"& .cm-codeblock-line": {
|
|
4843
4912
|
background: "var(--color-cm-codeblock)",
|
|
@@ -4869,16 +4938,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4869
4938
|
*/
|
|
4870
4939
|
".cm-table *": {
|
|
4871
4940
|
fontFamily: fontMono,
|
|
4941
|
+
lineHeight: 1.5,
|
|
4872
4942
|
textDecoration: "none !important"
|
|
4873
4943
|
},
|
|
4874
4944
|
".cm-table-head": {
|
|
4875
4945
|
padding: "2px 16px 2px 0px",
|
|
4946
|
+
overflowWrap: "break-word",
|
|
4947
|
+
whiteSpace: "pre-wrap",
|
|
4948
|
+
wordBreak: "keep-all",
|
|
4876
4949
|
textAlign: "left",
|
|
4877
|
-
|
|
4878
|
-
|
|
4950
|
+
color: "var(--color-subdued)",
|
|
4951
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4879
4952
|
},
|
|
4880
4953
|
".cm-table-cell": {
|
|
4881
|
-
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"
|
|
4882
4959
|
},
|
|
4883
4960
|
/**
|
|
4884
4961
|
* Image.
|
|
@@ -4894,12 +4971,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4894
4971
|
},
|
|
4895
4972
|
".cm-image-with-loader": {
|
|
4896
4973
|
display: "block",
|
|
4897
|
-
opacity:
|
|
4974
|
+
opacity: 0,
|
|
4898
4975
|
transitionDuration: "350ms",
|
|
4899
4976
|
transitionProperty: "opacity"
|
|
4900
4977
|
},
|
|
4901
4978
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4902
|
-
opacity:
|
|
4979
|
+
opacity: 1
|
|
4903
4980
|
},
|
|
4904
4981
|
".cm-image-wrapper": {
|
|
4905
4982
|
"grid-template-columns": "1fr",
|
|
@@ -4918,17 +4995,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4918
4995
|
// src/extensions/markdown/table.ts
|
|
4919
4996
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4920
4997
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4921
|
-
import { Decoration as Decoration10, EditorView as
|
|
4998
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4922
4999
|
var table = (options = {}) => {
|
|
4923
5000
|
return StateField8.define({
|
|
4924
5001
|
create: (state) => update(state, options),
|
|
4925
5002
|
update: (_, tr) => update(tr.state, options),
|
|
4926
|
-
provide: (field) =>
|
|
5003
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4927
5004
|
});
|
|
4928
5005
|
};
|
|
4929
5006
|
var update = (state, _options) => {
|
|
4930
5007
|
const builder = new RangeSetBuilder4();
|
|
4931
|
-
const
|
|
5008
|
+
const cursor = state.selection.main.head;
|
|
4932
5009
|
const tables = [];
|
|
4933
5010
|
const getTable = () => tables[tables.length - 1];
|
|
4934
5011
|
const getRow = () => {
|
|
@@ -4966,7 +5043,7 @@ var update = (state, _options) => {
|
|
|
4966
5043
|
}
|
|
4967
5044
|
});
|
|
4968
5045
|
tables.forEach((table2) => {
|
|
4969
|
-
const replace = state.readOnly ||
|
|
5046
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4970
5047
|
if (replace) {
|
|
4971
5048
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4972
5049
|
block: true,
|
|
@@ -4980,6 +5057,26 @@ var update = (state, _options) => {
|
|
|
4980
5057
|
});
|
|
4981
5058
|
return builder.finish();
|
|
4982
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
|
+
};
|
|
4983
5080
|
var TableWidget = class extends WidgetType6 {
|
|
4984
5081
|
_table;
|
|
4985
5082
|
constructor(_table) {
|
|
@@ -4999,7 +5096,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4999
5096
|
this._table.header?.forEach((cell) => {
|
|
5000
5097
|
const th = document.createElement("th");
|
|
5001
5098
|
th.setAttribute("class", "cm-table-head");
|
|
5002
|
-
tr.appendChild(th)
|
|
5099
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
5003
5100
|
});
|
|
5004
5101
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
5005
5102
|
this._table.rows?.forEach((row) => {
|
|
@@ -5007,7 +5104,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
5007
5104
|
row.forEach((cell) => {
|
|
5008
5105
|
const td = document.createElement("td");
|
|
5009
5106
|
td.setAttribute("class", "cm-table-cell");
|
|
5010
|
-
tr2.appendChild(td)
|
|
5107
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
5011
5108
|
});
|
|
5012
5109
|
});
|
|
5013
5110
|
return div;
|
|
@@ -5114,10 +5211,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5114
5211
|
class: "cm-code cm-codeblock-line"
|
|
5115
5212
|
});
|
|
5116
5213
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5117
|
-
class:
|
|
5214
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5118
5215
|
});
|
|
5119
5216
|
var fencedCodeLineLast = Decoration11.line({
|
|
5120
|
-
class:
|
|
5217
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5121
5218
|
});
|
|
5122
5219
|
var commentBlockLine = fencedCodeLine;
|
|
5123
5220
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5149,15 +5246,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5149
5246
|
const { state } = view;
|
|
5150
5247
|
const headerLevels = [];
|
|
5151
5248
|
const getHeaderLevels = (node, level) => {
|
|
5152
|
-
invariant4(level > 0, void 0, {
|
|
5153
|
-
F: __dxlog_file12,
|
|
5154
|
-
L: 179,
|
|
5155
|
-
S: void 0,
|
|
5156
|
-
A: [
|
|
5157
|
-
"level > 0",
|
|
5158
|
-
""
|
|
5159
|
-
]
|
|
5160
|
-
});
|
|
5249
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5161
5250
|
if (level > headerLevels.length) {
|
|
5162
5251
|
const len = headerLevels.length;
|
|
5163
5252
|
headerLevels.length = level;
|
|
@@ -5188,15 +5277,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5188
5277
|
listLevels.pop();
|
|
5189
5278
|
};
|
|
5190
5279
|
const getCurrentListLevel = () => {
|
|
5191
|
-
invariant4(listLevels.length, void 0, {
|
|
5192
|
-
F: __dxlog_file12,
|
|
5193
|
-
L: 201,
|
|
5194
|
-
S: void 0,
|
|
5195
|
-
A: [
|
|
5196
|
-
"listLevels.length",
|
|
5197
|
-
""
|
|
5198
|
-
]
|
|
5199
|
-
});
|
|
5280
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5200
5281
|
return listLevels[listLevels.length - 1];
|
|
5201
5282
|
};
|
|
5202
5283
|
const enterNode = (node) => {
|
|
@@ -5234,7 +5315,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5234
5315
|
deco: hide
|
|
5235
5316
|
});
|
|
5236
5317
|
} else {
|
|
5237
|
-
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(".") + "). ";
|
|
5238
5319
|
if (num.length) {
|
|
5239
5320
|
atomicDecoRanges.push({
|
|
5240
5321
|
from: mark.from,
|
|
@@ -5417,11 +5498,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5417
5498
|
}
|
|
5418
5499
|
decoRanges.push({
|
|
5419
5500
|
from: marks[0].to,
|
|
5420
|
-
to: marks[1].from,
|
|
5501
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5421
5502
|
deco: Decoration11.mark({
|
|
5422
5503
|
tagName: "a",
|
|
5423
5504
|
attributes: {
|
|
5424
|
-
class: "cm-link",
|
|
5505
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5425
5506
|
href: url,
|
|
5426
5507
|
rel: "noreferrer",
|
|
5427
5508
|
target: "_blank"
|
|
@@ -5499,18 +5580,21 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5499
5580
|
deco.add(from, to, d);
|
|
5500
5581
|
}
|
|
5501
5582
|
const atomicDeco = new RangeSetBuilder5();
|
|
5502
|
-
for (const { from, to, deco:
|
|
5503
|
-
|
|
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);
|
|
5504
5588
|
}
|
|
5505
5589
|
return {
|
|
5506
5590
|
deco: deco.finish(),
|
|
5507
5591
|
atomicDeco: atomicDeco.finish()
|
|
5508
5592
|
};
|
|
5509
5593
|
};
|
|
5510
|
-
var forceUpdate =
|
|
5594
|
+
var forceUpdate = StateEffect7.define();
|
|
5511
5595
|
var decorateMarkdown = (options = {}) => {
|
|
5512
5596
|
return [
|
|
5513
|
-
|
|
5597
|
+
ViewPlugin15.fromClass(class {
|
|
5514
5598
|
deco;
|
|
5515
5599
|
atomicDeco;
|
|
5516
5600
|
pendingUpdate;
|
|
@@ -5545,9 +5629,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5545
5629
|
}
|
|
5546
5630
|
}, {
|
|
5547
5631
|
provide: (plugin) => [
|
|
5548
|
-
Prec4.low(
|
|
5549
|
-
|
|
5550
|
-
|
|
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)
|
|
5551
5635
|
]
|
|
5552
5636
|
}),
|
|
5553
5637
|
image(),
|
|
@@ -5615,12 +5699,7 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5615
5699
|
(context) => {
|
|
5616
5700
|
log9.info("completion context", {
|
|
5617
5701
|
context
|
|
5618
|
-
}, {
|
|
5619
|
-
F: __dxlog_file13,
|
|
5620
|
-
L: 27,
|
|
5621
|
-
S: void 0,
|
|
5622
|
-
C: (f, a) => f(...a)
|
|
5623
|
-
});
|
|
5702
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5624
5703
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5625
5704
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5626
5705
|
return null;
|
|
@@ -5637,8 +5716,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5637
5716
|
};
|
|
5638
5717
|
|
|
5639
5718
|
// src/extensions/modal.ts
|
|
5640
|
-
import { StateEffect as
|
|
5641
|
-
var modalStateEffect =
|
|
5719
|
+
import { StateEffect as StateEffect8, StateField as StateField9 } from "@codemirror/state";
|
|
5720
|
+
var modalStateEffect = StateEffect8.define();
|
|
5642
5721
|
var modalStateField = StateField9.define({
|
|
5643
5722
|
create: () => false,
|
|
5644
5723
|
update: (value, tr) => {
|
|
@@ -5853,15 +5932,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5853
5932
|
break;
|
|
5854
5933
|
}
|
|
5855
5934
|
case "BulletList": {
|
|
5856
|
-
invariant5(current, void 0, {
|
|
5857
|
-
F: __dxlog_file14,
|
|
5858
|
-
L: 219,
|
|
5859
|
-
S: void 0,
|
|
5860
|
-
A: [
|
|
5861
|
-
"current",
|
|
5862
|
-
""
|
|
5863
|
-
]
|
|
5864
|
-
});
|
|
5935
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5865
5936
|
parent = current;
|
|
5866
5937
|
if (current) {
|
|
5867
5938
|
current.lineRange.to = current.node.from;
|
|
@@ -5870,15 +5941,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5870
5941
|
break;
|
|
5871
5942
|
}
|
|
5872
5943
|
case "ListItem": {
|
|
5873
|
-
invariant5(parent, void 0, {
|
|
5874
|
-
F: __dxlog_file14,
|
|
5875
|
-
L: 228,
|
|
5876
|
-
S: void 0,
|
|
5877
|
-
A: [
|
|
5878
|
-
"parent",
|
|
5879
|
-
""
|
|
5880
|
-
]
|
|
5881
|
-
});
|
|
5944
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5882
5945
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5883
5946
|
const docRange = {
|
|
5884
5947
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5912,42 +5975,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5912
5975
|
break;
|
|
5913
5976
|
}
|
|
5914
5977
|
case "ListMark": {
|
|
5915
|
-
invariant5(current, void 0, {
|
|
5916
|
-
F: __dxlog_file14,
|
|
5917
|
-
L: 272,
|
|
5918
|
-
S: void 0,
|
|
5919
|
-
A: [
|
|
5920
|
-
"current",
|
|
5921
|
-
""
|
|
5922
|
-
]
|
|
5923
|
-
});
|
|
5978
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5924
5979
|
current.type = "bullet";
|
|
5925
5980
|
current.contentRange.from = node.from + "- ".length;
|
|
5926
5981
|
break;
|
|
5927
5982
|
}
|
|
5928
5983
|
case "Task": {
|
|
5929
|
-
invariant5(current, void 0, {
|
|
5930
|
-
F: __dxlog_file14,
|
|
5931
|
-
L: 278,
|
|
5932
|
-
S: void 0,
|
|
5933
|
-
A: [
|
|
5934
|
-
"current",
|
|
5935
|
-
""
|
|
5936
|
-
]
|
|
5937
|
-
});
|
|
5984
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5938
5985
|
current.type = "task";
|
|
5939
5986
|
break;
|
|
5940
5987
|
}
|
|
5941
5988
|
case "TaskMarker": {
|
|
5942
|
-
invariant5(current, void 0, {
|
|
5943
|
-
F: __dxlog_file14,
|
|
5944
|
-
L: 283,
|
|
5945
|
-
S: void 0,
|
|
5946
|
-
A: [
|
|
5947
|
-
"current",
|
|
5948
|
-
""
|
|
5949
|
-
]
|
|
5950
|
-
});
|
|
5989
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5951
5990
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5952
5991
|
break;
|
|
5953
5992
|
}
|
|
@@ -5955,29 +5994,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5955
5994
|
},
|
|
5956
5995
|
leave: (node) => {
|
|
5957
5996
|
if (node.name === "BulletList") {
|
|
5958
|
-
invariant5(parent, void 0, {
|
|
5959
|
-
F: __dxlog_file14,
|
|
5960
|
-
L: 291,
|
|
5961
|
-
S: void 0,
|
|
5962
|
-
A: [
|
|
5963
|
-
"parent",
|
|
5964
|
-
""
|
|
5965
|
-
]
|
|
5966
|
-
});
|
|
5997
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5967
5998
|
prevSiblings[level--] = void 0;
|
|
5968
5999
|
parent = parent.parent;
|
|
5969
6000
|
}
|
|
5970
6001
|
}
|
|
5971
6002
|
});
|
|
5972
|
-
invariant5(tree, void 0, {
|
|
5973
|
-
F: __dxlog_file14,
|
|
5974
|
-
L: 298,
|
|
5975
|
-
S: void 0,
|
|
5976
|
-
A: [
|
|
5977
|
-
"tree",
|
|
5978
|
-
""
|
|
5979
|
-
]
|
|
5980
|
-
});
|
|
6003
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5981
6004
|
return tree;
|
|
5982
6005
|
};
|
|
5983
6006
|
return [
|
|
@@ -6262,17 +6285,17 @@ var commands = () => keymap11.of([
|
|
|
6262
6285
|
|
|
6263
6286
|
// src/extensions/outliner/outliner.ts
|
|
6264
6287
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6265
|
-
import { Decoration as Decoration12, EditorView as
|
|
6266
|
-
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";
|
|
6267
6290
|
|
|
6268
6291
|
// src/extensions/outliner/editor.ts
|
|
6269
6292
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6270
|
-
import { ViewPlugin as
|
|
6293
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6271
6294
|
import { log as log10 } from "@dxos/log";
|
|
6272
6295
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6273
6296
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6274
6297
|
var initialize = () => {
|
|
6275
|
-
return
|
|
6298
|
+
return ViewPlugin16.fromClass(class {
|
|
6276
6299
|
constructor(view) {
|
|
6277
6300
|
const first = view.state.doc.lineAt(0);
|
|
6278
6301
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6419,35 +6442,20 @@ var editor = () => [
|
|
|
6419
6442
|
text: insert.toString(),
|
|
6420
6443
|
length: insert.length
|
|
6421
6444
|
}
|
|
6422
|
-
}, {
|
|
6423
|
-
F: __dxlog_file15,
|
|
6424
|
-
L: 164,
|
|
6425
|
-
S: void 0,
|
|
6426
|
-
C: (f, a) => f(...a)
|
|
6427
|
-
});
|
|
6445
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6428
6446
|
}
|
|
6429
6447
|
});
|
|
6430
6448
|
if (changes.length > 0) {
|
|
6431
6449
|
log10("modified,", {
|
|
6432
6450
|
changes
|
|
6433
|
-
}, {
|
|
6434
|
-
F: __dxlog_file15,
|
|
6435
|
-
L: 175,
|
|
6436
|
-
S: void 0,
|
|
6437
|
-
C: (f, a) => f(...a)
|
|
6438
|
-
});
|
|
6451
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6439
6452
|
return [
|
|
6440
6453
|
{
|
|
6441
6454
|
changes
|
|
6442
6455
|
}
|
|
6443
6456
|
];
|
|
6444
6457
|
} else if (cancel) {
|
|
6445
|
-
log10("cancel", void 0, {
|
|
6446
|
-
F: __dxlog_file15,
|
|
6447
|
-
L: 178,
|
|
6448
|
-
S: void 0,
|
|
6449
|
-
C: (f, a) => f(...a)
|
|
6450
|
-
});
|
|
6458
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6451
6459
|
return [];
|
|
6452
6460
|
}
|
|
6453
6461
|
return tr;
|
|
@@ -6455,10 +6463,10 @@ var editor = () => [
|
|
|
6455
6463
|
];
|
|
6456
6464
|
|
|
6457
6465
|
// src/extensions/outliner/menu.ts
|
|
6458
|
-
import { EditorView as
|
|
6466
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6459
6467
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6460
6468
|
var menu = (options = {}) => [
|
|
6461
|
-
|
|
6469
|
+
ViewPlugin17.fromClass(class {
|
|
6462
6470
|
view;
|
|
6463
6471
|
tag;
|
|
6464
6472
|
rafId;
|
|
@@ -6520,7 +6528,7 @@ var menu = (options = {}) => [
|
|
|
6520
6528
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6521
6529
|
}
|
|
6522
6530
|
}),
|
|
6523
|
-
|
|
6531
|
+
EditorView25.theme({
|
|
6524
6532
|
".cm-popover-trigger": {
|
|
6525
6533
|
position: "fixed",
|
|
6526
6534
|
padding: "0",
|
|
@@ -6556,12 +6564,12 @@ var outliner = (_options = {}) => [
|
|
|
6556
6564
|
listPaddingLeft: 8
|
|
6557
6565
|
}),
|
|
6558
6566
|
// Researve space for menu.
|
|
6559
|
-
|
|
6567
|
+
EditorView26.contentAttributes.of({
|
|
6560
6568
|
class: "w-full !mr-[3rem]"
|
|
6561
6569
|
})
|
|
6562
6570
|
];
|
|
6563
6571
|
var decorations = () => [
|
|
6564
|
-
|
|
6572
|
+
ViewPlugin18.fromClass(class {
|
|
6565
6573
|
decorations = Decoration12.none;
|
|
6566
6574
|
constructor(view) {
|
|
6567
6575
|
this.updateDecorations(view.state, view);
|
|
@@ -6586,7 +6594,7 @@ var decorations = () => [
|
|
|
6586
6594
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6587
6595
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6588
6596
|
decorations2.push(Decoration12.line({
|
|
6589
|
-
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"))
|
|
6590
6598
|
}).range(line.from, line.from));
|
|
6591
6599
|
}
|
|
6592
6600
|
}
|
|
@@ -6596,7 +6604,7 @@ var decorations = () => [
|
|
|
6596
6604
|
decorations: (v) => v.decorations
|
|
6597
6605
|
}),
|
|
6598
6606
|
// Theme.
|
|
6599
|
-
|
|
6607
|
+
EditorView26.theme(Object.assign({
|
|
6600
6608
|
".cm-list-item": {
|
|
6601
6609
|
borderLeftWidth: "1px",
|
|
6602
6610
|
borderRightWidth: "1px",
|
|
@@ -6631,28 +6639,57 @@ var decorations = () => [
|
|
|
6631
6639
|
|
|
6632
6640
|
// src/extensions/preview/preview.ts
|
|
6633
6641
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6634
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
|
|
6635
|
-
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();
|
|
6636
6646
|
var preview = (options = {}) => {
|
|
6647
|
+
const viewRef = {
|
|
6648
|
+
current: void 0
|
|
6649
|
+
};
|
|
6637
6650
|
return [
|
|
6638
6651
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6639
6652
|
// "Block decorations may not be specified via plugins".
|
|
6640
6653
|
StateField11.define({
|
|
6641
|
-
create: (state) => buildDecorations3(state, options),
|
|
6654
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6642
6655
|
update: (decorations2, tr) => {
|
|
6643
|
-
if (tr.docChanged) {
|
|
6644
|
-
return buildDecorations3(tr.state, options);
|
|
6656
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6657
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6645
6658
|
}
|
|
6646
6659
|
return decorations2.map(tr.changes);
|
|
6647
6660
|
},
|
|
6648
6661
|
provide: (field) => [
|
|
6649
|
-
|
|
6650
|
-
|
|
6662
|
+
EditorView27.decorations.from(field),
|
|
6663
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6651
6664
|
]
|
|
6665
|
+
}),
|
|
6666
|
+
ViewPlugin19.define((view) => {
|
|
6667
|
+
viewRef.current = view;
|
|
6668
|
+
return {
|
|
6669
|
+
destroy() {
|
|
6670
|
+
viewRef.current = void 0;
|
|
6671
|
+
}
|
|
6672
|
+
};
|
|
6652
6673
|
})
|
|
6653
6674
|
];
|
|
6654
6675
|
};
|
|
6655
|
-
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) => {
|
|
6656
6693
|
const builder = new RangeSetBuilder6();
|
|
6657
6694
|
syntaxTree10(state).iterate({
|
|
6658
6695
|
enter: (node) => {
|
|
@@ -6664,8 +6701,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6664
6701
|
case "Link": {
|
|
6665
6702
|
const link = getLinkRef(state, node.node);
|
|
6666
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;
|
|
6667
6709
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6668
|
-
widget: new PreviewInlineWidget(options,
|
|
6710
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6669
6711
|
side: 1
|
|
6670
6712
|
}));
|
|
6671
6713
|
}
|
|
@@ -6757,7 +6799,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6757
6799
|
};
|
|
6758
6800
|
|
|
6759
6801
|
// src/extensions/replacer.ts
|
|
6760
|
-
import { EditorView as
|
|
6802
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6761
6803
|
var defaultReplacements = [
|
|
6762
6804
|
{
|
|
6763
6805
|
input: "--",
|
|
@@ -6820,7 +6862,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6820
6862
|
const sortedReplacements = [
|
|
6821
6863
|
...replacements
|
|
6822
6864
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6823
|
-
return
|
|
6865
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6824
6866
|
if (insert.length !== 1) {
|
|
6825
6867
|
return false;
|
|
6826
6868
|
}
|
|
@@ -6854,12 +6896,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6854
6896
|
});
|
|
6855
6897
|
};
|
|
6856
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
|
+
|
|
6857
6956
|
// src/extensions/submit.ts
|
|
6858
6957
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6859
|
-
import { keymap as
|
|
6958
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6860
6959
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6861
6960
|
return [
|
|
6862
|
-
Prec6.highest(
|
|
6961
|
+
Prec6.highest(keymap13.of([
|
|
6863
6962
|
{
|
|
6864
6963
|
key: "Enter",
|
|
6865
6964
|
preventDefault: true,
|
|
@@ -6904,6 +7003,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6904
7003
|
// src/extensions/tags/extended-markdown.ts
|
|
6905
7004
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6906
7005
|
import { parseMixed } from "@lezer/common";
|
|
7006
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6907
7007
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6908
7008
|
return [
|
|
6909
7009
|
createMarkdownExtensions({
|
|
@@ -6915,13 +7015,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6915
7015
|
{
|
|
6916
7016
|
name: "SetextHeading",
|
|
6917
7017
|
parse: () => false
|
|
6918
|
-
}
|
|
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)
|
|
6919
7022
|
]
|
|
6920
7023
|
}
|
|
6921
7024
|
]
|
|
6922
7025
|
})
|
|
6923
7026
|
];
|
|
6924
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
|
+
};
|
|
6925
7077
|
var mixedParser = (registry) => {
|
|
6926
7078
|
const customTags = Object.keys(registry ?? {});
|
|
6927
7079
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6955,219 +7107,793 @@ var mixedParser = (registry) => {
|
|
|
6955
7107
|
});
|
|
6956
7108
|
};
|
|
6957
7109
|
|
|
6958
|
-
// src/extensions/tags/
|
|
6959
|
-
import { StateEffect as
|
|
6960
|
-
import { Decoration as Decoration14, EditorView as
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
var
|
|
6964
|
-
var
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
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) => {
|
|
6975
7133
|
for (const effect of tr.effects) {
|
|
6976
|
-
if (effect.is(
|
|
6977
|
-
|
|
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
|
+
}
|
|
7153
|
+
}
|
|
7154
|
+
}
|
|
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
|
+
}
|
|
6978
7327
|
}
|
|
6979
7328
|
}
|
|
6980
7329
|
if (tr.docChanged) {
|
|
6981
|
-
|
|
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
|
+
}
|
|
6982
7348
|
}
|
|
6983
|
-
return
|
|
7349
|
+
return {
|
|
7350
|
+
text,
|
|
7351
|
+
head,
|
|
7352
|
+
insertAt
|
|
7353
|
+
};
|
|
6984
7354
|
}
|
|
6985
7355
|
});
|
|
6986
|
-
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 {
|
|
6987
7388
|
view;
|
|
6988
|
-
|
|
7389
|
+
_raf;
|
|
7390
|
+
_activeStreamTag = null;
|
|
6989
7391
|
constructor(view) {
|
|
6990
7392
|
this.view = view;
|
|
6991
7393
|
}
|
|
6992
7394
|
update(update2) {
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
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();
|
|
7000
7402
|
}
|
|
7001
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
|
+
};
|
|
7002
7478
|
destroy() {
|
|
7003
|
-
|
|
7479
|
+
if (this._raf !== void 0) {
|
|
7480
|
+
cancelAnimationFrame(this._raf);
|
|
7481
|
+
}
|
|
7004
7482
|
}
|
|
7005
7483
|
});
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
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
|
+
}
|
|
7012
7525
|
}
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
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({
|
|
7016
7541
|
widget: new CursorWidget(),
|
|
7017
7542
|
side: 1
|
|
7018
|
-
}).range(
|
|
7543
|
+
}).range(pos)
|
|
7019
7544
|
]);
|
|
7020
7545
|
},
|
|
7021
|
-
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
|
+
}
|
|
7022
7573
|
});
|
|
7023
7574
|
return [
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7575
|
+
visibilityField,
|
|
7576
|
+
decorationField,
|
|
7577
|
+
timerPlugin
|
|
7027
7578
|
];
|
|
7028
7579
|
};
|
|
7029
|
-
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
|
+
}
|
|
7030
7586
|
toDOM() {
|
|
7031
|
-
const inner = Domino3.of("span").text("\
|
|
7032
|
-
animation: "blink
|
|
7587
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7588
|
+
animation: "blink 1s infinite",
|
|
7589
|
+
animationDelay: "250ms"
|
|
7033
7590
|
});
|
|
7034
7591
|
return Domino3.of("span").style({
|
|
7035
7592
|
opacity: "0.8"
|
|
7036
|
-
}).
|
|
7593
|
+
}).append(inner).root;
|
|
7037
7594
|
}
|
|
7038
7595
|
};
|
|
7039
|
-
var
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
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
|
+
};
|
|
7058
7632
|
}
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
isReset = true;
|
|
7064
|
-
}
|
|
7065
|
-
});
|
|
7633
|
+
if (buffer[close - 1] === "/") {
|
|
7634
|
+
return {
|
|
7635
|
+
count: close + 1 - start
|
|
7636
|
+
};
|
|
7066
7637
|
}
|
|
7067
|
-
|
|
7068
|
-
|
|
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;
|
|
7069
7693
|
}
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
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") {
|
|
7073
7739
|
return;
|
|
7074
7740
|
}
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
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;
|
|
7079
7746
|
}
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
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;
|
|
7091
7778
|
constructor(view) {
|
|
7092
|
-
this.
|
|
7779
|
+
this.decorations = buildDecorations5(view);
|
|
7093
7780
|
}
|
|
7094
7781
|
update(update2) {
|
|
7095
|
-
if (
|
|
7096
|
-
|
|
7782
|
+
if (update2.docChanged) {
|
|
7783
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7097
7784
|
}
|
|
7098
|
-
|
|
7099
|
-
|
|
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));
|
|
7100
7831
|
return;
|
|
7101
7832
|
}
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
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
|
+
}
|
|
7105
7850
|
}
|
|
7106
|
-
const totalDelay = FADE_IN_DURATION + removalDelay;
|
|
7107
|
-
const id = setTimeout(() => {
|
|
7108
|
-
this.view.dispatch({
|
|
7109
|
-
effects: removeDecoration.of({
|
|
7110
|
-
from: fromB,
|
|
7111
|
-
to: toB
|
|
7112
|
-
})
|
|
7113
|
-
});
|
|
7114
|
-
this._timers.delete(key);
|
|
7115
|
-
}, totalDelay);
|
|
7116
|
-
this._timers.set(key, id);
|
|
7117
|
-
});
|
|
7118
|
-
}
|
|
7119
|
-
destroy() {
|
|
7120
|
-
for (const id of this._timers.values()) {
|
|
7121
|
-
clearTimeout(id);
|
|
7122
7851
|
}
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
}
|
|
7852
|
+
});
|
|
7853
|
+
return Decoration17.set(ranges, true);
|
|
7854
|
+
};
|
|
7126
7855
|
return [
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
},
|
|
7136
|
-
"@keyframes fade-in": {
|
|
7137
|
-
"0%": {
|
|
7138
|
-
opacity: "0"
|
|
7139
|
-
},
|
|
7140
|
-
"80%": {
|
|
7141
|
-
opacity: "1"
|
|
7142
|
-
},
|
|
7143
|
-
"100%": {
|
|
7144
|
-
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);
|
|
7145
7864
|
}
|
|
7146
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": {}
|
|
7147
7880
|
})
|
|
7148
7881
|
];
|
|
7149
7882
|
};
|
|
7150
7883
|
|
|
7151
7884
|
// src/extensions/tags/xml-tags.ts
|
|
7152
7885
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7153
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7154
|
-
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";
|
|
7155
7888
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7156
7889
|
import { log as log11 } from "@dxos/log";
|
|
7890
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7157
7891
|
|
|
7158
7892
|
// src/extensions/tags/xml-util.ts
|
|
7159
7893
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7160
7894
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7161
7895
|
var nodeToJson = (state, node) => {
|
|
7162
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7163
|
-
F: __dxlog_file16,
|
|
7164
|
-
L: 18,
|
|
7165
|
-
S: void 0,
|
|
7166
|
-
A: [
|
|
7167
|
-
"node.type.name === 'Element'",
|
|
7168
|
-
"'Node is not an Element'"
|
|
7169
|
-
]
|
|
7170
|
-
});
|
|
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'"] });
|
|
7171
7897
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7172
7898
|
if (openTag) {
|
|
7173
7899
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7199,13 +7925,23 @@ var nodeToJson = (state, node) => {
|
|
|
7199
7925
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7200
7926
|
const children = [];
|
|
7201
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
|
+
};
|
|
7202
7939
|
while (child) {
|
|
7203
7940
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7204
7941
|
if (child.type.name === "Text") {
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
}
|
|
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)));
|
|
7209
7945
|
} else if (child.type.name === "Element") {
|
|
7210
7946
|
const data = nodeToJson(state, child);
|
|
7211
7947
|
if (data) {
|
|
@@ -7215,26 +7951,63 @@ var nodeToJson = (state, node) => {
|
|
|
7215
7951
|
}
|
|
7216
7952
|
child = child.nextSibling;
|
|
7217
7953
|
}
|
|
7954
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7955
|
+
children[0] = children[0].trimStart();
|
|
7956
|
+
}
|
|
7218
7957
|
if (children.length > 0) {
|
|
7219
|
-
|
|
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;
|
|
7220
7967
|
}
|
|
7221
7968
|
}
|
|
7222
7969
|
return tag;
|
|
7223
7970
|
}
|
|
7224
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
|
+
};
|
|
7225
7996
|
|
|
7226
7997
|
// src/extensions/tags/xml-tags.ts
|
|
7227
7998
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
7228
|
-
var navigatePreviousEffect =
|
|
7229
|
-
var navigateNextEffect =
|
|
7999
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8000
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7230
8001
|
var getXmlTextChild = (children) => {
|
|
7231
8002
|
const child = children?.[0];
|
|
7232
8003
|
return typeof child === "string" ? child : null;
|
|
7233
8004
|
};
|
|
7234
|
-
var
|
|
7235
|
-
var
|
|
7236
|
-
var
|
|
7237
|
-
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({
|
|
7238
8011
|
create: () => void 0,
|
|
7239
8012
|
update: (value, tr) => {
|
|
7240
8013
|
for (const effect of tr.effects) {
|
|
@@ -7245,7 +8018,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7245
8018
|
return value;
|
|
7246
8019
|
}
|
|
7247
8020
|
});
|
|
7248
|
-
var widgetStateMapStateField =
|
|
8021
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7249
8022
|
create: () => ({}),
|
|
7250
8023
|
update: (map, tr) => {
|
|
7251
8024
|
for (const effect of tr.effects) {
|
|
@@ -7257,12 +8030,7 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7257
8030
|
log11("widget updated", {
|
|
7258
8031
|
id,
|
|
7259
8032
|
value
|
|
7260
|
-
}, {
|
|
7261
|
-
F: __dxlog_file17,
|
|
7262
|
-
L: 153,
|
|
7263
|
-
S: void 0,
|
|
7264
|
-
C: (f, a) => f(...a)
|
|
7265
|
-
});
|
|
8033
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7266
8034
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7267
8035
|
return {
|
|
7268
8036
|
...map,
|
|
@@ -7292,12 +8060,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7292
8060
|
log11("widget mounted", {
|
|
7293
8061
|
id: state.id,
|
|
7294
8062
|
tag: state.props._tag
|
|
7295
|
-
}, {
|
|
7296
|
-
F: __dxlog_file17,
|
|
7297
|
-
L: 206,
|
|
7298
|
-
S: void 0,
|
|
7299
|
-
C: (f, a) => f(...a)
|
|
7300
|
-
});
|
|
8063
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7301
8064
|
widgets.set(state.id, state);
|
|
7302
8065
|
setWidgets?.([
|
|
7303
8066
|
...widgets.values()
|
|
@@ -7308,12 +8071,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7308
8071
|
log11("widget unmounted", {
|
|
7309
8072
|
id,
|
|
7310
8073
|
tag: state?.props._tag
|
|
7311
|
-
}, {
|
|
7312
|
-
F: __dxlog_file17,
|
|
7313
|
-
L: 212,
|
|
7314
|
-
S: void 0,
|
|
7315
|
-
C: (f, a) => f(...a)
|
|
7316
|
-
});
|
|
8074
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7317
8075
|
widgets.delete(id);
|
|
7318
8076
|
setWidgets?.([
|
|
7319
8077
|
...widgets.values()
|
|
@@ -7322,7 +8080,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7322
8080
|
};
|
|
7323
8081
|
return notifier;
|
|
7324
8082
|
};
|
|
7325
|
-
var keyHandlers =
|
|
8083
|
+
var keyHandlers = keymap14.of([
|
|
7326
8084
|
{
|
|
7327
8085
|
key: "Mod-ArrowUp",
|
|
7328
8086
|
run: (view) => {
|
|
@@ -7343,7 +8101,7 @@ var keyHandlers = keymap13.of([
|
|
|
7343
8101
|
}
|
|
7344
8102
|
]);
|
|
7345
8103
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7346
|
-
return
|
|
8104
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7347
8105
|
update2.transactions.forEach((transaction) => {
|
|
7348
8106
|
for (const effect of transaction.effects) {
|
|
7349
8107
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7428,7 +8186,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7428
8186
|
});
|
|
7429
8187
|
});
|
|
7430
8188
|
};
|
|
7431
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8189
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7432
8190
|
update(update2) {
|
|
7433
8191
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7434
8192
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7455,14 +8213,14 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7455
8213
|
}
|
|
7456
8214
|
}
|
|
7457
8215
|
});
|
|
7458
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8216
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7459
8217
|
create: (state) => {
|
|
7460
8218
|
return buildDecorations4(state, {
|
|
7461
8219
|
from: 0,
|
|
7462
8220
|
to: state.doc.length
|
|
7463
8221
|
}, registry, notifier);
|
|
7464
8222
|
},
|
|
7465
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8223
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7466
8224
|
for (const effect of tr.effects) {
|
|
7467
8225
|
if (effect.is(xmlTagResetEffect)) {
|
|
7468
8226
|
if (tr.docChanged) {
|
|
@@ -7473,7 +8231,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7473
8231
|
}
|
|
7474
8232
|
return {
|
|
7475
8233
|
from: 0,
|
|
7476
|
-
decorations:
|
|
8234
|
+
decorations: Decoration18.none
|
|
7477
8235
|
};
|
|
7478
8236
|
}
|
|
7479
8237
|
}
|
|
@@ -7484,24 +8242,23 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7484
8242
|
log11("document reset", {
|
|
7485
8243
|
from,
|
|
7486
8244
|
to: state.doc.length
|
|
7487
|
-
}, {
|
|
7488
|
-
F: __dxlog_file17,
|
|
7489
|
-
L: 374,
|
|
7490
|
-
S: void 0,
|
|
7491
|
-
C: (f, a) => f(...a)
|
|
7492
|
-
});
|
|
8245
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7493
8246
|
return buildDecorations4(state, {
|
|
7494
8247
|
from: 0,
|
|
7495
8248
|
to: state.doc.length
|
|
7496
8249
|
}, registry, notifier);
|
|
7497
8250
|
} else {
|
|
8251
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7498
8252
|
const result = buildDecorations4(state, {
|
|
7499
|
-
from,
|
|
8253
|
+
from: rebuildFrom,
|
|
7500
8254
|
to: state.doc.length
|
|
7501
8255
|
}, registry, notifier);
|
|
7502
8256
|
return {
|
|
7503
8257
|
from: result.from,
|
|
8258
|
+
streamingFrom: result.streamingFrom,
|
|
7504
8259
|
decorations: decorations2.update({
|
|
8260
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8261
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7505
8262
|
add: decorationSetToArray(result.decorations)
|
|
7506
8263
|
})
|
|
7507
8264
|
};
|
|
@@ -7509,12 +8266,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7509
8266
|
}
|
|
7510
8267
|
return {
|
|
7511
8268
|
from,
|
|
8269
|
+
streamingFrom,
|
|
7512
8270
|
decorations: decorations2
|
|
7513
8271
|
};
|
|
7514
8272
|
},
|
|
7515
8273
|
provide: (field) => [
|
|
7516
|
-
|
|
7517
|
-
|
|
8274
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8275
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7518
8276
|
]
|
|
7519
8277
|
});
|
|
7520
8278
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7525,10 +8283,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7525
8283
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7526
8284
|
return {
|
|
7527
8285
|
from: range.from,
|
|
7528
|
-
decorations:
|
|
8286
|
+
decorations: Decoration18.none
|
|
7529
8287
|
};
|
|
7530
8288
|
}
|
|
7531
8289
|
let last = range.from;
|
|
8290
|
+
let streamingFrom;
|
|
7532
8291
|
tree.iterate({
|
|
7533
8292
|
from: range.from,
|
|
7534
8293
|
to: range.to,
|
|
@@ -7541,21 +8300,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7541
8300
|
if (args) {
|
|
7542
8301
|
const def = registry[args._tag];
|
|
7543
8302
|
if (def) {
|
|
8303
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8304
|
+
return false;
|
|
8305
|
+
}
|
|
7544
8306
|
const { block, factory, Component } = def;
|
|
7545
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7546
8307
|
const nodeRange = {
|
|
7547
8308
|
from: node.node.from,
|
|
7548
8309
|
to: node.node.to
|
|
7549
8310
|
};
|
|
8311
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8312
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7550
8313
|
const props = {
|
|
7551
|
-
|
|
8314
|
+
id: widgetId,
|
|
7552
8315
|
range: nodeRange,
|
|
8316
|
+
context,
|
|
7553
8317
|
...args,
|
|
7554
8318
|
...widgetState
|
|
7555
8319
|
};
|
|
7556
|
-
const widget = factory ? factory(props) : Component ?
|
|
8320
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7557
8321
|
if (widget) {
|
|
7558
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8322
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7559
8323
|
widget,
|
|
7560
8324
|
block,
|
|
7561
8325
|
atomic: true,
|
|
@@ -7567,20 +8331,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7567
8331
|
}
|
|
7568
8332
|
}
|
|
7569
8333
|
} catch (err) {
|
|
7570
|
-
log11.catch(err, void 0, {
|
|
7571
|
-
F: __dxlog_file17,
|
|
7572
|
-
L: 459,
|
|
7573
|
-
S: void 0,
|
|
7574
|
-
C: (f, a) => f(...a)
|
|
7575
|
-
});
|
|
8334
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7576
8335
|
}
|
|
7577
8336
|
return false;
|
|
7578
8337
|
}
|
|
7579
8338
|
}
|
|
7580
8339
|
}
|
|
7581
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
|
+
}
|
|
7582
8397
|
return {
|
|
7583
8398
|
from: last,
|
|
8399
|
+
streamingFrom,
|
|
7584
8400
|
decorations: builder.finish()
|
|
7585
8401
|
};
|
|
7586
8402
|
};
|
|
@@ -7589,108 +8405,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7589
8405
|
Component;
|
|
7590
8406
|
props;
|
|
7591
8407
|
notifier;
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
S: this,
|
|
7599
|
-
A: [
|
|
7600
|
-
"id",
|
|
7601
|
-
""
|
|
7602
|
-
]
|
|
7603
|
-
});
|
|
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", ""] });
|
|
7604
8414
|
}
|
|
7605
8415
|
get root() {
|
|
7606
|
-
return this
|
|
8416
|
+
return this.#root;
|
|
7607
8417
|
}
|
|
7608
8418
|
eq(other) {
|
|
8419
|
+
if (this.streaming) {
|
|
8420
|
+
return false;
|
|
8421
|
+
}
|
|
7609
8422
|
return this.id === other.id;
|
|
7610
8423
|
}
|
|
7611
8424
|
ignoreEvent() {
|
|
7612
8425
|
return true;
|
|
7613
8426
|
}
|
|
7614
|
-
toDOM(
|
|
7615
|
-
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
|
+
});
|
|
7616
8446
|
this.notifier.mounted({
|
|
7617
8447
|
id: this.id,
|
|
7618
|
-
root: this
|
|
7619
|
-
props
|
|
8448
|
+
root: this.#root,
|
|
8449
|
+
props,
|
|
7620
8450
|
Component: this.Component
|
|
7621
8451
|
});
|
|
7622
|
-
return
|
|
8452
|
+
return true;
|
|
7623
8453
|
}
|
|
7624
8454
|
destroy(_dom) {
|
|
7625
8455
|
this.notifier.unmounted(this.id);
|
|
7626
|
-
this
|
|
8456
|
+
this.#root = null;
|
|
8457
|
+
this.#view = void 0;
|
|
7627
8458
|
}
|
|
7628
8459
|
};
|
|
7629
|
-
|
|
7630
|
-
// src/extensions/typewriter.ts
|
|
7631
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
7632
|
-
var defaultItems = [
|
|
7633
|
-
"hello world!",
|
|
7634
|
-
"this is a test.",
|
|
7635
|
-
"this is [DXOS](https://dxos.org)"
|
|
7636
|
-
];
|
|
7637
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7638
|
-
let t;
|
|
7639
|
-
let idx = 0;
|
|
7640
|
-
return [
|
|
7641
|
-
keymap14.of([
|
|
7642
|
-
{
|
|
7643
|
-
// Reset.
|
|
7644
|
-
key: "alt-meta-'",
|
|
7645
|
-
run: () => {
|
|
7646
|
-
clearTimeout(t);
|
|
7647
|
-
idx = 0;
|
|
7648
|
-
return true;
|
|
7649
|
-
}
|
|
7650
|
-
},
|
|
7651
|
-
{
|
|
7652
|
-
// Next prompt.
|
|
7653
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
7654
|
-
key: "Shift-Meta-'",
|
|
7655
|
-
run: (view) => {
|
|
7656
|
-
clearTimeout(t);
|
|
7657
|
-
const text = items[idx++];
|
|
7658
|
-
if (idx === items?.length) {
|
|
7659
|
-
idx = 0;
|
|
7660
|
-
}
|
|
7661
|
-
let i = 0;
|
|
7662
|
-
const insert = (d = 0) => {
|
|
7663
|
-
t = setTimeout(() => {
|
|
7664
|
-
const pos = view.state.selection.main.head;
|
|
7665
|
-
view.dispatch({
|
|
7666
|
-
changes: {
|
|
7667
|
-
from: pos,
|
|
7668
|
-
insert: text[i++]
|
|
7669
|
-
},
|
|
7670
|
-
selection: {
|
|
7671
|
-
anchor: pos + 1
|
|
7672
|
-
}
|
|
7673
|
-
});
|
|
7674
|
-
if (i < text.length) {
|
|
7675
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
7676
|
-
}
|
|
7677
|
-
}, d);
|
|
7678
|
-
};
|
|
7679
|
-
insert();
|
|
7680
|
-
return true;
|
|
7681
|
-
}
|
|
7682
|
-
}
|
|
7683
|
-
])
|
|
7684
|
-
];
|
|
7685
|
-
};
|
|
7686
8460
|
export {
|
|
7687
8461
|
Cursor,
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
EditorState3 as EditorState,
|
|
7691
|
-
EditorView30 as EditorView,
|
|
7692
|
-
EditorViewMode,
|
|
7693
|
-
EditorViewModes,
|
|
8462
|
+
EditorState4 as EditorState,
|
|
8463
|
+
EditorView33 as EditorView,
|
|
7694
8464
|
Inline,
|
|
7695
8465
|
InputModeExtensions,
|
|
7696
8466
|
List,
|
|
@@ -7707,6 +8477,7 @@ export {
|
|
|
7707
8477
|
addStyle,
|
|
7708
8478
|
annotations,
|
|
7709
8479
|
autoScroll,
|
|
8480
|
+
autoScrollEffect,
|
|
7710
8481
|
autocomplete,
|
|
7711
8482
|
automerge,
|
|
7712
8483
|
awareness,
|
|
@@ -7720,6 +8491,7 @@ export {
|
|
|
7720
8491
|
commentClickedEffect,
|
|
7721
8492
|
comments,
|
|
7722
8493
|
commentsState,
|
|
8494
|
+
compactSlots,
|
|
7723
8495
|
convertTreeToJson,
|
|
7724
8496
|
createBasicExtensions,
|
|
7725
8497
|
createComment,
|
|
@@ -7743,12 +8515,12 @@ export {
|
|
|
7743
8515
|
defaultThemeSlots,
|
|
7744
8516
|
deleteItem,
|
|
7745
8517
|
documentId,
|
|
8518
|
+
documentSlots,
|
|
7746
8519
|
dropFile,
|
|
8520
|
+
editorClassNames,
|
|
7747
8521
|
editorInputMode,
|
|
7748
|
-
editorSlots,
|
|
7749
|
-
editorWidth,
|
|
7750
|
-
editorWithToolbarLayout,
|
|
7751
8522
|
extendedMarkdown,
|
|
8523
|
+
fader,
|
|
7752
8524
|
filterChars,
|
|
7753
8525
|
flattenRect,
|
|
7754
8526
|
focus,
|
|
@@ -7784,6 +8556,7 @@ export {
|
|
|
7784
8556
|
markdownTagsExtensions,
|
|
7785
8557
|
matchCompletion,
|
|
7786
8558
|
mention,
|
|
8559
|
+
mobileSlots,
|
|
7787
8560
|
modalStateEffect,
|
|
7788
8561
|
modalStateField,
|
|
7789
8562
|
moveItemDown,
|
|
@@ -7803,6 +8576,7 @@ export {
|
|
|
7803
8576
|
removeList,
|
|
7804
8577
|
removeStyle,
|
|
7805
8578
|
replacer,
|
|
8579
|
+
scrollPastEnd,
|
|
7806
8580
|
scrollThreadIntoView,
|
|
7807
8581
|
scrollToLine,
|
|
7808
8582
|
scroller,
|
|
@@ -7815,9 +8589,8 @@ export {
|
|
|
7815
8589
|
setSelection,
|
|
7816
8590
|
setStyle,
|
|
7817
8591
|
singleValueFacet,
|
|
7818
|
-
|
|
8592
|
+
snippets2 as snippets,
|
|
7819
8593
|
staticCompletion,
|
|
7820
|
-
streamer,
|
|
7821
8594
|
submit,
|
|
7822
8595
|
tabbable,
|
|
7823
8596
|
table,
|
|
@@ -7836,7 +8609,12 @@ export {
|
|
|
7836
8609
|
treeFacet,
|
|
7837
8610
|
typeahead,
|
|
7838
8611
|
typewriter,
|
|
8612
|
+
typewriterBypass,
|
|
8613
|
+
typewriterDrainingEffect,
|
|
7839
8614
|
wrapWithCatch,
|
|
8615
|
+
xmlBlockDecoration,
|
|
8616
|
+
xmlElementLength,
|
|
8617
|
+
xmlFormatting,
|
|
7840
8618
|
xmlTagContextEffect,
|
|
7841
8619
|
xmlTagResetEffect,
|
|
7842
8620
|
xmlTagUpdateEffect,
|