@dxos/ui-editor 0.8.4-main.d05673bc65 → 0.8.4-main.fcc0d83b33
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 +1524 -755
- 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 +1524 -754
- 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 +29 -32
- package/src/defaults.ts +33 -20
- package/src/extensions/auto-scroll.ts +115 -9
- package/src/extensions/automerge/automerge.test.tsx +28 -8
- package/src/extensions/automerge/automerge.ts +2 -5
- package/src/extensions/comments.ts +0 -1
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +26 -8
- package/src/extensions/folding.ts +3 -20
- package/src/extensions/index.ts +2 -1
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +11 -9
- package/src/extensions/markdown/highlight.ts +4 -10
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +37 -4
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +0 -1
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +54 -7
- package/src/extensions/scroll-past-end.ts +32 -0
- package/src/extensions/scroller.ts +48 -24
- 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,14 +1120,16 @@ var automerge = (accessor) => {
|
|
|
1046
1120
|
const value = DocAccessor.getValue(accessor);
|
|
1047
1121
|
const current = this._view.state.doc.toString();
|
|
1048
1122
|
if (value !== current) {
|
|
1049
|
-
console.warn("ENABLING INITIAL SYNC -- THIS MAY BE A REGRESSION");
|
|
1050
1123
|
this._view.dispatch({
|
|
1051
1124
|
changes: {
|
|
1052
1125
|
from: 0,
|
|
1053
1126
|
to: this._view.state.doc.length,
|
|
1054
1127
|
insert: value
|
|
1055
1128
|
},
|
|
1056
|
-
annotations:
|
|
1129
|
+
annotations: [
|
|
1130
|
+
initialSync,
|
|
1131
|
+
reconcileAnnotation.of(true)
|
|
1132
|
+
]
|
|
1057
1133
|
});
|
|
1058
1134
|
}
|
|
1059
1135
|
});
|
|
@@ -1105,10 +1181,7 @@ var awareness = (provider = dummyProvider) => {
|
|
|
1105
1181
|
];
|
|
1106
1182
|
};
|
|
1107
1183
|
var RemoteSelectionsDecorator = class {
|
|
1108
|
-
_ctx = new Context(void 0, {
|
|
1109
|
-
F: __dxlog_file5,
|
|
1110
|
-
L: 80
|
|
1111
|
-
});
|
|
1184
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
|
|
1112
1185
|
_cursorConverter;
|
|
1113
1186
|
_provider;
|
|
1114
1187
|
_lastAnchor;
|
|
@@ -1339,10 +1412,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1339
1412
|
this._info = info;
|
|
1340
1413
|
}
|
|
1341
1414
|
open() {
|
|
1342
|
-
this._ctx = new Context2(void 0, {
|
|
1343
|
-
F: __dxlog_file6,
|
|
1344
|
-
L: 57
|
|
1345
|
-
});
|
|
1415
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
|
|
1346
1416
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1347
1417
|
if (this._localState) {
|
|
1348
1418
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1369,12 +1439,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1369
1439
|
}).catch((err) => {
|
|
1370
1440
|
log5.debug("failed to query awareness", {
|
|
1371
1441
|
err
|
|
1372
|
-
}, {
|
|
1373
|
-
F: __dxlog_file6,
|
|
1374
|
-
L: 91,
|
|
1375
|
-
S: this,
|
|
1376
|
-
C: (f, a) => f(...a)
|
|
1377
|
-
});
|
|
1442
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
|
|
1378
1443
|
});
|
|
1379
1444
|
}
|
|
1380
1445
|
close() {
|
|
@@ -1386,15 +1451,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1386
1451
|
return Array.from(this._remoteStates.values());
|
|
1387
1452
|
}
|
|
1388
1453
|
update(position) {
|
|
1389
|
-
invariant(this._postTask, void 0, {
|
|
1390
|
-
F: __dxlog_file6,
|
|
1391
|
-
L: 106,
|
|
1392
|
-
S: this,
|
|
1393
|
-
A: [
|
|
1394
|
-
"this._postTask",
|
|
1395
|
-
""
|
|
1396
|
-
]
|
|
1397
|
-
});
|
|
1454
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1398
1455
|
this._localState = {
|
|
1399
1456
|
peerId: this._peerId,
|
|
1400
1457
|
position,
|
|
@@ -1403,27 +1460,11 @@ var SpaceAwarenessProvider = class {
|
|
|
1403
1460
|
this._postTask.schedule();
|
|
1404
1461
|
}
|
|
1405
1462
|
_handleQueryMessage() {
|
|
1406
|
-
invariant(this._postTask, void 0, {
|
|
1407
|
-
F: __dxlog_file6,
|
|
1408
|
-
L: 117,
|
|
1409
|
-
S: this,
|
|
1410
|
-
A: [
|
|
1411
|
-
"this._postTask",
|
|
1412
|
-
""
|
|
1413
|
-
]
|
|
1414
|
-
});
|
|
1463
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1415
1464
|
this._postTask.schedule();
|
|
1416
1465
|
}
|
|
1417
1466
|
_handlePostMessage(message) {
|
|
1418
|
-
invariant(message.kind === "post", void 0, {
|
|
1419
|
-
F: __dxlog_file6,
|
|
1420
|
-
L: 122,
|
|
1421
|
-
S: this,
|
|
1422
|
-
A: [
|
|
1423
|
-
"message.kind === 'post'",
|
|
1424
|
-
""
|
|
1425
|
-
]
|
|
1426
|
-
});
|
|
1467
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1427
1468
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1428
1469
|
this.remoteStateChange.emit();
|
|
1429
1470
|
}
|
|
@@ -1552,15 +1593,7 @@ var Blaster = class {
|
|
|
1552
1593
|
return this._node;
|
|
1553
1594
|
}
|
|
1554
1595
|
initialize() {
|
|
1555
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1556
|
-
F: __dxlog_file7,
|
|
1557
|
-
L: 142,
|
|
1558
|
-
S: this,
|
|
1559
|
-
A: [
|
|
1560
|
-
"!this._canvas && !this._ctx",
|
|
1561
|
-
""
|
|
1562
|
-
]
|
|
1563
|
-
});
|
|
1596
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1564
1597
|
this._canvas = document.createElement("canvas");
|
|
1565
1598
|
this._canvas.id = "code-blast-canvas";
|
|
1566
1599
|
this._canvas.style.position = "absolute";
|
|
@@ -1589,15 +1622,7 @@ var Blaster = class {
|
|
|
1589
1622
|
}
|
|
1590
1623
|
}
|
|
1591
1624
|
start() {
|
|
1592
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1593
|
-
F: __dxlog_file7,
|
|
1594
|
-
L: 181,
|
|
1595
|
-
S: this,
|
|
1596
|
-
A: [
|
|
1597
|
-
"this._canvas && this._ctx",
|
|
1598
|
-
""
|
|
1599
|
-
]
|
|
1600
|
-
});
|
|
1625
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1601
1626
|
this._running = true;
|
|
1602
1627
|
this.loop();
|
|
1603
1628
|
}
|
|
@@ -1832,13 +1857,13 @@ var blocks = () => [
|
|
|
1832
1857
|
];
|
|
1833
1858
|
|
|
1834
1859
|
// src/extensions/bookmarks.ts
|
|
1835
|
-
import { Prec as Prec3, StateEffect as
|
|
1860
|
+
import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
|
|
1836
1861
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1837
1862
|
import { log as log6 } from "@dxos/log";
|
|
1838
1863
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1839
|
-
var addBookmark =
|
|
1840
|
-
var removeBookmark =
|
|
1841
|
-
var clearBookmarks =
|
|
1864
|
+
var addBookmark = StateEffect4.define();
|
|
1865
|
+
var removeBookmark = StateEffect4.define();
|
|
1866
|
+
var clearBookmarks = StateEffect4.define();
|
|
1842
1867
|
var bookmarks = () => {
|
|
1843
1868
|
return [
|
|
1844
1869
|
bookmarksField,
|
|
@@ -1847,12 +1872,7 @@ var bookmarks = () => {
|
|
|
1847
1872
|
key: "Mod-ArrowUp",
|
|
1848
1873
|
run: (view) => {
|
|
1849
1874
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1850
|
-
log6("up", bookmarks2, {
|
|
1851
|
-
F: __dxlog_file8,
|
|
1852
|
-
L: 29,
|
|
1853
|
-
S: void 0,
|
|
1854
|
-
C: (f, a) => f(...a)
|
|
1855
|
-
});
|
|
1875
|
+
log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
|
|
1856
1876
|
return true;
|
|
1857
1877
|
}
|
|
1858
1878
|
},
|
|
@@ -1860,12 +1880,7 @@ var bookmarks = () => {
|
|
|
1860
1880
|
key: "Mod-ArrowDown",
|
|
1861
1881
|
run: (view) => {
|
|
1862
1882
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1863
|
-
log6("down", bookmarks2, {
|
|
1864
|
-
F: __dxlog_file8,
|
|
1865
|
-
L: 37,
|
|
1866
|
-
S: void 0,
|
|
1867
|
-
C: (f, a) => f(...a)
|
|
1868
|
-
});
|
|
1883
|
+
log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
|
|
1869
1884
|
return true;
|
|
1870
1885
|
}
|
|
1871
1886
|
}
|
|
@@ -1902,7 +1917,7 @@ var bookmarksField = StateField2.define({
|
|
|
1902
1917
|
|
|
1903
1918
|
// src/extensions/comments.ts
|
|
1904
1919
|
import { invertedEffects } from "@codemirror/commands";
|
|
1905
|
-
import { StateEffect as
|
|
1920
|
+
import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
|
|
1906
1921
|
import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1907
1922
|
import sortBy from "lodash.sortby";
|
|
1908
1923
|
import { debounce as debounce2 } from "@dxos/async";
|
|
@@ -1930,28 +1945,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1930
1945
|
};
|
|
1931
1946
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1932
1947
|
getState: (id) => {
|
|
1933
|
-
invariant3(id, void 0, {
|
|
1934
|
-
F: __dxlog_file9,
|
|
1935
|
-
L: 47,
|
|
1936
|
-
S: void 0,
|
|
1937
|
-
A: [
|
|
1938
|
-
"id",
|
|
1939
|
-
""
|
|
1940
|
-
]
|
|
1941
|
-
});
|
|
1948
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
|
|
1942
1949
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1943
1950
|
return state ? JSON.parse(state) : void 0;
|
|
1944
1951
|
},
|
|
1945
1952
|
setState: (id, state) => {
|
|
1946
|
-
invariant3(id, void 0, {
|
|
1947
|
-
F: __dxlog_file9,
|
|
1948
|
-
L: 53,
|
|
1949
|
-
S: void 0,
|
|
1950
|
-
A: [
|
|
1951
|
-
"id",
|
|
1952
|
-
""
|
|
1953
|
-
]
|
|
1954
|
-
});
|
|
1953
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
|
|
1955
1954
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1956
1955
|
}
|
|
1957
1956
|
});
|
|
@@ -2004,9 +2003,9 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
2004
2003
|
|
|
2005
2004
|
// src/extensions/comments.ts
|
|
2006
2005
|
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
2007
|
-
var setComments =
|
|
2008
|
-
var setSelection =
|
|
2009
|
-
var setCommentState =
|
|
2006
|
+
var setComments = StateEffect5.define();
|
|
2007
|
+
var setSelection = StateEffect5.define();
|
|
2008
|
+
var setCommentState = StateEffect5.define();
|
|
2010
2009
|
var commentsState = StateField3.define({
|
|
2011
2010
|
create: (state) => ({
|
|
2012
2011
|
id: state.facet(documentId),
|
|
@@ -2073,12 +2072,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2073
2072
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2074
2073
|
const range = comment.range;
|
|
2075
2074
|
if (!range) {
|
|
2076
|
-
log7.warn("Invalid range:", range, {
|
|
2077
|
-
F: __dxlog_file10,
|
|
2078
|
-
L: 140,
|
|
2079
|
-
S: void 0,
|
|
2080
|
-
C: (f, a) => f(...a)
|
|
2081
|
-
});
|
|
2075
|
+
log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
|
|
2082
2076
|
return void 0;
|
|
2083
2077
|
} else if (range.from === range.to) {
|
|
2084
2078
|
return void 0;
|
|
@@ -2088,7 +2082,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2088
2082
|
}).filter(isNonNullable);
|
|
2089
2083
|
return Decoration7.set(decorations2);
|
|
2090
2084
|
});
|
|
2091
|
-
var commentClickedEffect =
|
|
2085
|
+
var commentClickedEffect = StateEffect5.define();
|
|
2092
2086
|
var handleCommentClick = EditorView11.domEventHandlers({
|
|
2093
2087
|
click: (event, view) => {
|
|
2094
2088
|
let target = event.target;
|
|
@@ -2191,10 +2185,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2191
2185
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2192
2186
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2193
2187
|
if (!exists) {
|
|
2194
|
-
const
|
|
2188
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2195
2189
|
onUpdate({
|
|
2196
2190
|
id: comment.id,
|
|
2197
|
-
cursor
|
|
2191
|
+
cursor
|
|
2198
2192
|
});
|
|
2199
2193
|
}
|
|
2200
2194
|
}
|
|
@@ -2206,7 +2200,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2206
2200
|
from: changes.mapPos(comment.from, 1),
|
|
2207
2201
|
to: changes.mapPos(comment.to, 1)
|
|
2208
2202
|
});
|
|
2209
|
-
var restoreCommentEffect =
|
|
2203
|
+
var restoreCommentEffect = StateEffect5.define({
|
|
2210
2204
|
map: mapTrackedComment
|
|
2211
2205
|
});
|
|
2212
2206
|
var createComment = (view) => {
|
|
@@ -2223,13 +2217,13 @@ var createComment = (view) => {
|
|
|
2223
2217
|
}
|
|
2224
2218
|
});
|
|
2225
2219
|
}
|
|
2226
|
-
const
|
|
2220
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2227
2221
|
from,
|
|
2228
2222
|
to
|
|
2229
2223
|
});
|
|
2230
|
-
if (
|
|
2224
|
+
if (cursor) {
|
|
2231
2225
|
options.onCreate?.({
|
|
2232
|
-
cursor
|
|
2226
|
+
cursor,
|
|
2233
2227
|
from,
|
|
2234
2228
|
location: view.coordsAtPos(from)
|
|
2235
2229
|
});
|
|
@@ -2470,7 +2464,7 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2470
2464
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2471
2465
|
import { searchKeymap } from "@codemirror/search";
|
|
2472
2466
|
import { EditorState } from "@codemirror/state";
|
|
2473
|
-
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";
|
|
2474
2468
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2475
2469
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2476
2470
|
import { generateName } from "@dxos/display-name";
|
|
@@ -2482,28 +2476,28 @@ import { EditorView as EditorView13 } from "@codemirror/view";
|
|
|
2482
2476
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2483
2477
|
var headings = {
|
|
2484
2478
|
1: {
|
|
2485
|
-
className: "text-
|
|
2486
|
-
fontSize: "var(--text-
|
|
2479
|
+
className: "text-3xl",
|
|
2480
|
+
fontSize: "var(--text-3xl)",
|
|
2487
2481
|
lineHeight: "var(--text-4xl--line-height)"
|
|
2488
2482
|
},
|
|
2489
2483
|
2: {
|
|
2490
|
-
className: "text-
|
|
2491
|
-
fontSize: "var(--text-
|
|
2484
|
+
className: "text-2xl",
|
|
2485
|
+
fontSize: "var(--text-2xl)",
|
|
2492
2486
|
lineHeight: "var(--text-3xl--line-height)"
|
|
2493
2487
|
},
|
|
2494
2488
|
3: {
|
|
2495
|
-
className: "text-
|
|
2496
|
-
fontSize: "var(--text-
|
|
2489
|
+
className: "text-xl",
|
|
2490
|
+
fontSize: "var(--text-xl)",
|
|
2497
2491
|
lineHeight: "var(--text-2xl--line-height)"
|
|
2498
2492
|
},
|
|
2499
2493
|
4: {
|
|
2500
|
-
className: "text-
|
|
2501
|
-
fontSize: "var(--text-
|
|
2494
|
+
className: "text-lg",
|
|
2495
|
+
fontSize: "var(--text-lg)",
|
|
2502
2496
|
lineHeight: "var(--text-xl--line-height)"
|
|
2503
2497
|
},
|
|
2504
2498
|
5: {
|
|
2505
|
-
className: "text-
|
|
2506
|
-
fontSize: "var(--text-
|
|
2499
|
+
className: "text-base",
|
|
2500
|
+
fontSize: "var(--text-base)",
|
|
2507
2501
|
lineHeight: "var(--text-lg--line-height)"
|
|
2508
2502
|
},
|
|
2509
2503
|
6: {
|
|
@@ -2512,20 +2506,20 @@ var headings = {
|
|
|
2512
2506
|
lineHeight: "var(--text-base--line-height)"
|
|
2513
2507
|
}
|
|
2514
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';
|
|
2515
2511
|
var markdownTheme = {
|
|
2516
|
-
code: "font-mono
|
|
2517
|
-
codeMark: "font-mono
|
|
2518
|
-
mark: "
|
|
2512
|
+
code: "font-mono! cm-code-inline",
|
|
2513
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2514
|
+
mark: "font-mono!",
|
|
2519
2515
|
heading: (level) => ({
|
|
2520
|
-
className: mx3(headings[level].className, "font-light text-cm-heading"),
|
|
2516
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2521
2517
|
color: "var(--color-cm-heading) !important",
|
|
2522
2518
|
lineHeight: headings[level].lineHeight,
|
|
2523
2519
|
fontSize: headings[level].fontSize,
|
|
2524
2520
|
fontWeight: "100 !important"
|
|
2525
2521
|
})
|
|
2526
2522
|
};
|
|
2527
|
-
var fontBody = "Inter Variable, ui-sans-serif, system-ui, sans-serif";
|
|
2528
|
-
var fontMono = "JetBrains Mono Variable, ui-monospace, Cascadia Code, Source Code Pro, monospace";
|
|
2529
2523
|
var baseTheme = EditorView13.baseTheme({
|
|
2530
2524
|
/**
|
|
2531
2525
|
* Outer frame.
|
|
@@ -2538,12 +2532,21 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2538
2532
|
* Scroller
|
|
2539
2533
|
*/
|
|
2540
2534
|
".cm-scroller": {
|
|
2541
|
-
|
|
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"
|
|
2542
2539
|
},
|
|
2543
2540
|
".cm-scroller::-webkit-scrollbar": {
|
|
2544
|
-
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"
|
|
2545
2549
|
},
|
|
2546
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2547
2550
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2548
2551
|
background: "transparent",
|
|
2549
2552
|
transition: "background 0.15s"
|
|
@@ -2557,7 +2560,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2557
2560
|
*/
|
|
2558
2561
|
".cm-content": {
|
|
2559
2562
|
padding: "unset",
|
|
2560
|
-
lineHeight: "24px",
|
|
2561
2563
|
color: "unset"
|
|
2562
2564
|
},
|
|
2563
2565
|
/**
|
|
@@ -2588,9 +2590,16 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2588
2590
|
* Line.
|
|
2589
2591
|
*/
|
|
2590
2592
|
".cm-line": {
|
|
2591
|
-
lineHeight:
|
|
2593
|
+
lineHeight: 1.5,
|
|
2592
2594
|
paddingInline: 0
|
|
2593
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
|
+
},
|
|
2594
2603
|
".cm-activeLine": {
|
|
2595
2604
|
background: "var(--color-cm-active-line)"
|
|
2596
2605
|
},
|
|
@@ -2768,10 +2777,9 @@ var editorGutter = EditorView13.theme({
|
|
|
2768
2777
|
}
|
|
2769
2778
|
});
|
|
2770
2779
|
var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
2771
|
-
//
|
|
2780
|
+
// Main content.
|
|
2772
2781
|
".cm-scroller": {
|
|
2773
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2774
|
-
fontSize: "16px"
|
|
2782
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2775
2783
|
},
|
|
2776
2784
|
// Maintain defaults for UI components.
|
|
2777
2785
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2781,9 +2789,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2781
2789
|
});
|
|
2782
2790
|
|
|
2783
2791
|
// src/extensions/focus.ts
|
|
2784
|
-
import { StateEffect as
|
|
2792
|
+
import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
|
|
2785
2793
|
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
2786
|
-
var focusEffect =
|
|
2794
|
+
var focusEffect = StateEffect6.define();
|
|
2787
2795
|
var focusField = StateField5.define({
|
|
2788
2796
|
create: () => false,
|
|
2789
2797
|
update: (value, tr) => {
|
|
@@ -2811,9 +2819,32 @@ var focus = [
|
|
|
2811
2819
|
})
|
|
2812
2820
|
];
|
|
2813
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
|
+
|
|
2814
2845
|
// src/extensions/factories.ts
|
|
2815
2846
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2816
|
-
var tabbable =
|
|
2847
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2817
2848
|
tabindex: "0"
|
|
2818
2849
|
});
|
|
2819
2850
|
var filterChars = (chars) => {
|
|
@@ -2866,13 +2897,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2866
2897
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2867
2898
|
return [
|
|
2868
2899
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2869
|
-
|
|
2870
|
-
log8.catch(err, void 0, {
|
|
2871
|
-
F: __dxlog_file11,
|
|
2872
|
-
L: 131,
|
|
2873
|
-
S: void 0,
|
|
2874
|
-
C: (f, a) => f(...a)
|
|
2875
|
-
});
|
|
2900
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2901
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2876
2902
|
}),
|
|
2877
2903
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2878
2904
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2881,7 +2907,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2881
2907
|
props.drawSelection && drawSelection({
|
|
2882
2908
|
cursorBlinkRate: 1200
|
|
2883
2909
|
}),
|
|
2884
|
-
props.editable !== void 0 &&
|
|
2910
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2885
2911
|
props.focus && focus,
|
|
2886
2912
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2887
2913
|
props.history && history(),
|
|
@@ -2889,9 +2915,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2889
2915
|
lineNumbers(),
|
|
2890
2916
|
editorGutter
|
|
2891
2917
|
],
|
|
2892
|
-
props.lineWrapping &&
|
|
2918
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2893
2919
|
props.placeholder && placeholder2(props.placeholder),
|
|
2894
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),
|
|
2895
2928
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2896
2929
|
props.tabbable && tabbable,
|
|
2897
2930
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2934,24 +2967,29 @@ var defaultStyles = {
|
|
|
2934
2967
|
dark: vscodeDarkStyle,
|
|
2935
2968
|
light: vscodeLightStyle
|
|
2936
2969
|
};
|
|
2937
|
-
var createThemeExtensions = ({ monospace,
|
|
2970
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2938
2971
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2939
2972
|
return [
|
|
2940
2973
|
baseTheme,
|
|
2941
|
-
|
|
2974
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2942
2975
|
createFontTheme({
|
|
2943
2976
|
monospace
|
|
2944
2977
|
}),
|
|
2945
2978
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2946
|
-
slots.editor?.className &&
|
|
2979
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2947
2980
|
class: slots.editor.className
|
|
2948
2981
|
}),
|
|
2949
|
-
slots.content?.className &&
|
|
2982
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2950
2983
|
class: slots.content.className
|
|
2951
2984
|
}),
|
|
2952
|
-
slots.
|
|
2985
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2953
2986
|
constructor(view) {
|
|
2954
|
-
|
|
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
|
+
}
|
|
2955
2993
|
}
|
|
2956
2994
|
})
|
|
2957
2995
|
].filter(isTruthy2);
|
|
@@ -2980,7 +3018,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2980
3018
|
|
|
2981
3019
|
// src/extensions/folding.ts
|
|
2982
3020
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2983
|
-
import { EditorView as
|
|
3021
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2984
3022
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2985
3023
|
var folding = () => {
|
|
2986
3024
|
return [
|
|
@@ -2988,13 +3026,14 @@ var folding = () => {
|
|
|
2988
3026
|
placeholderDOM: () => Domino2.of("span").root
|
|
2989
3027
|
}),
|
|
2990
3028
|
foldGutter({
|
|
3029
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2991
3030
|
markerDOM: (open) => {
|
|
2992
|
-
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({
|
|
2993
3032
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2994
3033
|
}))).root;
|
|
2995
3034
|
}
|
|
2996
3035
|
}),
|
|
2997
|
-
|
|
3036
|
+
EditorView17.theme({
|
|
2998
3037
|
".cm-foldGutter": {
|
|
2999
3038
|
opacity: 0.3,
|
|
3000
3039
|
transition: "opacity 0.3s",
|
|
@@ -3008,7 +3047,7 @@ var folding = () => {
|
|
|
3008
3047
|
};
|
|
3009
3048
|
|
|
3010
3049
|
// src/extensions/hashtag.ts
|
|
3011
|
-
import { Decoration as Decoration8, EditorView as
|
|
3050
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3012
3051
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
3013
3052
|
var TagWidget = class extends WidgetType4 {
|
|
3014
3053
|
_text;
|
|
@@ -3029,7 +3068,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3029
3068
|
})
|
|
3030
3069
|
});
|
|
3031
3070
|
var hashtag = () => [
|
|
3032
|
-
|
|
3071
|
+
ViewPlugin13.fromClass(class {
|
|
3033
3072
|
tags;
|
|
3034
3073
|
constructor(view) {
|
|
3035
3074
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3039,11 +3078,11 @@ var hashtag = () => [
|
|
|
3039
3078
|
}
|
|
3040
3079
|
}, {
|
|
3041
3080
|
decorations: (instance) => instance.tags,
|
|
3042
|
-
provide: (plugin) =>
|
|
3081
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
3043
3082
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3044
3083
|
})
|
|
3045
3084
|
}),
|
|
3046
|
-
|
|
3085
|
+
EditorView18.theme({
|
|
3047
3086
|
".cm-tag": {
|
|
3048
3087
|
borderRadius: "4px",
|
|
3049
3088
|
marginRight: "6px",
|
|
@@ -3098,18 +3137,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3098
3137
|
};
|
|
3099
3138
|
|
|
3100
3139
|
// src/extensions/listener.ts
|
|
3101
|
-
import { EditorView as
|
|
3140
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3102
3141
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3103
3142
|
var listener = ({ onFocus, onChange }) => {
|
|
3104
3143
|
return [
|
|
3105
|
-
onFocus &&
|
|
3144
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3106
3145
|
onFocus({
|
|
3107
3146
|
id: state.facet(documentId),
|
|
3108
3147
|
focusing
|
|
3109
3148
|
});
|
|
3110
3149
|
return null;
|
|
3111
3150
|
}),
|
|
3112
|
-
onChange &&
|
|
3151
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3113
3152
|
if (docChanged) {
|
|
3114
3153
|
onChange({
|
|
3115
3154
|
id: state.facet(documentId),
|
|
@@ -3124,7 +3163,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3124
3163
|
import { snippet } from "@codemirror/autocomplete";
|
|
3125
3164
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3126
3165
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3127
|
-
import { EditorView as
|
|
3166
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3128
3167
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3129
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;
|
|
3130
3169
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4213,7 +4252,7 @@ var getFormatting = (state) => {
|
|
|
4213
4252
|
};
|
|
4214
4253
|
};
|
|
4215
4254
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4216
|
-
return
|
|
4255
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4217
4256
|
if (update2.docChanged || update2.selectionSet) {
|
|
4218
4257
|
onStateChange(getFormatting(update2.state));
|
|
4219
4258
|
}
|
|
@@ -4274,8 +4313,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4274
4313
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4275
4314
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4276
4315
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4277
|
-
import {
|
|
4278
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4316
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4279
4317
|
import { languages } from "@codemirror/language-data";
|
|
4280
4318
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4281
4319
|
import { isTruthy as isTruthy3 } from "@dxos/util";
|
|
@@ -4285,11 +4323,6 @@ import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
|
4285
4323
|
import { HighlightStyle as HighlightStyle2 } from "@codemirror/language";
|
|
4286
4324
|
import { Tag, styleTags, tags } from "@lezer/highlight";
|
|
4287
4325
|
import { Table } from "@lezer/markdown";
|
|
4288
|
-
var styles4 = {
|
|
4289
|
-
code: "font-mono no-underline! text-cm-code",
|
|
4290
|
-
codeMark: "font-mono text-cm-code-mark",
|
|
4291
|
-
mark: "opacity-50"
|
|
4292
|
-
};
|
|
4293
4326
|
var markdownTags = {
|
|
4294
4327
|
Blockquote: Tag.define(),
|
|
4295
4328
|
CodeMark: Tag.define(),
|
|
@@ -4371,7 +4404,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4371
4404
|
markdownTags.LinkReference,
|
|
4372
4405
|
markdownTags.ListMark
|
|
4373
4406
|
],
|
|
4374
|
-
class:
|
|
4407
|
+
class: markdownTheme.mark
|
|
4375
4408
|
},
|
|
4376
4409
|
// Markdown marks.
|
|
4377
4410
|
{
|
|
@@ -4382,7 +4415,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4382
4415
|
markdownTags.QuoteMark,
|
|
4383
4416
|
markdownTags.EmphasisMark
|
|
4384
4417
|
],
|
|
4385
|
-
class:
|
|
4418
|
+
class: markdownTheme.mark
|
|
4386
4419
|
},
|
|
4387
4420
|
// E.g., code block language (after ```).
|
|
4388
4421
|
{
|
|
@@ -4391,7 +4424,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4391
4424
|
tags.function(tags.variableName),
|
|
4392
4425
|
tags.labelName
|
|
4393
4426
|
],
|
|
4394
|
-
class:
|
|
4427
|
+
class: markdownTheme.codeMark
|
|
4395
4428
|
},
|
|
4396
4429
|
// Fonts.
|
|
4397
4430
|
{
|
|
@@ -4457,7 +4490,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4457
4490
|
markdownTags.CodeText,
|
|
4458
4491
|
markdownTags.InlineCode
|
|
4459
4492
|
],
|
|
4460
|
-
class:
|
|
4493
|
+
class: markdownTheme.code
|
|
4461
4494
|
},
|
|
4462
4495
|
{
|
|
4463
4496
|
tag: [
|
|
@@ -4487,15 +4520,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4487
4520
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4488
4521
|
base: markdownLanguage2,
|
|
4489
4522
|
// Languages for syntax highlighting fenced code blocks.
|
|
4523
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4490
4524
|
defaultCodeLanguage: jsonLanguage,
|
|
4491
|
-
codeLanguages:
|
|
4525
|
+
codeLanguages: [
|
|
4526
|
+
...options.codeLanguages ?? [],
|
|
4527
|
+
...languages
|
|
4528
|
+
],
|
|
4492
4529
|
// Don't complete HTML tags.
|
|
4493
4530
|
completeHTMLTags: false,
|
|
4494
4531
|
// Parser extensions.
|
|
4495
4532
|
extensions: [
|
|
4496
4533
|
// GFM provided by default.
|
|
4497
4534
|
markdownTagsExtensions,
|
|
4498
|
-
...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
|
|
4499
4540
|
]
|
|
4500
4541
|
}),
|
|
4501
4542
|
// Custom styles.
|
|
@@ -4510,18 +4551,13 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4510
4551
|
].filter(isTruthy3))
|
|
4511
4552
|
];
|
|
4512
4553
|
};
|
|
4513
|
-
var
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
]
|
|
4519
|
-
|
|
4520
|
-
"xml",
|
|
4521
|
-
"xhtml"
|
|
4522
|
-
],
|
|
4523
|
-
load: async () => xml()
|
|
4524
|
-
});
|
|
4554
|
+
var noFencedCodeFolding = {
|
|
4555
|
+
props: [
|
|
4556
|
+
foldNodeProp.add({
|
|
4557
|
+
FencedCode: () => null
|
|
4558
|
+
})
|
|
4559
|
+
]
|
|
4560
|
+
};
|
|
4525
4561
|
var defaultExtensions = () => [
|
|
4526
4562
|
noSetExtHeading,
|
|
4527
4563
|
noHtml
|
|
@@ -4541,19 +4577,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4541
4577
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4542
4578
|
});
|
|
4543
4579
|
var convertTreeToJson = (state) => {
|
|
4544
|
-
const treeToJson = (
|
|
4580
|
+
const treeToJson = (cursor) => {
|
|
4545
4581
|
const node = {
|
|
4546
|
-
type:
|
|
4547
|
-
from:
|
|
4548
|
-
to:
|
|
4549
|
-
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(),
|
|
4550
4586
|
children: []
|
|
4551
4587
|
};
|
|
4552
|
-
if (
|
|
4588
|
+
if (cursor.firstChild()) {
|
|
4553
4589
|
do {
|
|
4554
|
-
node.children.push(treeToJson(
|
|
4555
|
-
} while (
|
|
4556
|
-
|
|
4590
|
+
node.children.push(treeToJson(cursor));
|
|
4591
|
+
} while (cursor.nextSibling());
|
|
4592
|
+
cursor.parent();
|
|
4557
4593
|
}
|
|
4558
4594
|
return node;
|
|
4559
4595
|
};
|
|
@@ -4562,17 +4598,16 @@ var convertTreeToJson = (state) => {
|
|
|
4562
4598
|
|
|
4563
4599
|
// src/extensions/markdown/decorate.ts
|
|
4564
4600
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4565
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4566
|
-
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";
|
|
4567
4603
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4568
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4569
4604
|
|
|
4570
4605
|
// src/extensions/markdown/changes.ts
|
|
4571
4606
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4572
4607
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4573
|
-
import { ViewPlugin as
|
|
4608
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4574
4609
|
var adjustChanges = () => {
|
|
4575
|
-
return
|
|
4610
|
+
return ViewPlugin14.fromClass(class {
|
|
4576
4611
|
update(update2) {
|
|
4577
4612
|
const tree = syntaxTree4(update2.state);
|
|
4578
4613
|
const adjustments = [];
|
|
@@ -4714,7 +4749,7 @@ var getValidUrl = (str) => {
|
|
|
4714
4749
|
// src/extensions/markdown/image.ts
|
|
4715
4750
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4716
4751
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4717
|
-
import { Decoration as Decoration9, EditorView as
|
|
4752
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4718
4753
|
var image = (_options = {}) => {
|
|
4719
4754
|
return [
|
|
4720
4755
|
StateField7.define({
|
|
@@ -4725,10 +4760,10 @@ var image = (_options = {}) => {
|
|
|
4725
4760
|
if (!tr.docChanged && !tr.selection) {
|
|
4726
4761
|
return value;
|
|
4727
4762
|
}
|
|
4728
|
-
const
|
|
4763
|
+
const cursor = tr.state.selection.main.head;
|
|
4729
4764
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4730
|
-
let from = Math.min(
|
|
4731
|
-
let to = Math.max(
|
|
4765
|
+
let from = Math.min(cursor, oldCursor);
|
|
4766
|
+
let to = Math.max(cursor, oldCursor);
|
|
4732
4767
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4733
4768
|
from = Math.min(from, fromB);
|
|
4734
4769
|
to = Math.max(to, toB);
|
|
@@ -4742,19 +4777,19 @@ var image = (_options = {}) => {
|
|
|
4742
4777
|
add: buildDecorations(tr.state, from, to)
|
|
4743
4778
|
});
|
|
4744
4779
|
},
|
|
4745
|
-
provide: (field) =>
|
|
4780
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4746
4781
|
})
|
|
4747
4782
|
];
|
|
4748
4783
|
};
|
|
4749
4784
|
var buildDecorations = (state, from, to) => {
|
|
4750
4785
|
const decorations2 = [];
|
|
4751
|
-
const
|
|
4786
|
+
const cursor = state.selection.main.head;
|
|
4752
4787
|
syntaxTree5(state).iterate({
|
|
4753
4788
|
enter: (node) => {
|
|
4754
4789
|
if (node.name === "Image") {
|
|
4755
4790
|
const urlNode = node.node.getChild("URL");
|
|
4756
4791
|
if (urlNode) {
|
|
4757
|
-
const hide2 = state.readOnly ||
|
|
4792
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4758
4793
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4759
4794
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4760
4795
|
return;
|
|
@@ -4802,10 +4837,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4802
4837
|
};
|
|
4803
4838
|
|
|
4804
4839
|
// src/extensions/markdown/styles.ts
|
|
4805
|
-
import { EditorView as
|
|
4840
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4806
4841
|
var bulletListIndentationWidth = 24;
|
|
4807
4842
|
var orderedListIndentationWidth = 36;
|
|
4808
|
-
var formattingStyles =
|
|
4843
|
+
var formattingStyles = EditorView22.theme({
|
|
4809
4844
|
/**
|
|
4810
4845
|
* Horizontal rule.
|
|
4811
4846
|
*/
|
|
@@ -4840,13 +4875,38 @@ var formattingStyles = EditorView21.theme({
|
|
|
4840
4875
|
background: "var(--color-cm-codeblock)",
|
|
4841
4876
|
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4842
4877
|
paddingLeft: "1rem",
|
|
4843
|
-
margin:
|
|
4878
|
+
margin: 0
|
|
4844
4879
|
},
|
|
4845
4880
|
/**
|
|
4846
4881
|
* Code and codeblocks.
|
|
4847
4882
|
*/
|
|
4883
|
+
"& code": {
|
|
4884
|
+
fontFamily: fontMono,
|
|
4885
|
+
color: "var(--color-cm-code)",
|
|
4886
|
+
whiteSpace: "nowrap"
|
|
4887
|
+
},
|
|
4848
4888
|
"& .cm-code": {
|
|
4849
|
-
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"
|
|
4850
4910
|
},
|
|
4851
4911
|
"& .cm-codeblock-line": {
|
|
4852
4912
|
background: "var(--color-cm-codeblock)",
|
|
@@ -4878,16 +4938,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4878
4938
|
*/
|
|
4879
4939
|
".cm-table *": {
|
|
4880
4940
|
fontFamily: fontMono,
|
|
4941
|
+
lineHeight: 1.5,
|
|
4881
4942
|
textDecoration: "none !important"
|
|
4882
4943
|
},
|
|
4883
4944
|
".cm-table-head": {
|
|
4884
4945
|
padding: "2px 16px 2px 0px",
|
|
4946
|
+
overflowWrap: "break-word",
|
|
4947
|
+
whiteSpace: "pre-wrap",
|
|
4948
|
+
wordBreak: "keep-all",
|
|
4885
4949
|
textAlign: "left",
|
|
4886
|
-
|
|
4887
|
-
|
|
4950
|
+
color: "var(--color-subdued)",
|
|
4951
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4888
4952
|
},
|
|
4889
4953
|
".cm-table-cell": {
|
|
4890
|
-
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"
|
|
4891
4959
|
},
|
|
4892
4960
|
/**
|
|
4893
4961
|
* Image.
|
|
@@ -4903,12 +4971,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4903
4971
|
},
|
|
4904
4972
|
".cm-image-with-loader": {
|
|
4905
4973
|
display: "block",
|
|
4906
|
-
opacity:
|
|
4974
|
+
opacity: 0,
|
|
4907
4975
|
transitionDuration: "350ms",
|
|
4908
4976
|
transitionProperty: "opacity"
|
|
4909
4977
|
},
|
|
4910
4978
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4911
|
-
opacity:
|
|
4979
|
+
opacity: 1
|
|
4912
4980
|
},
|
|
4913
4981
|
".cm-image-wrapper": {
|
|
4914
4982
|
"grid-template-columns": "1fr",
|
|
@@ -4927,17 +4995,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4927
4995
|
// src/extensions/markdown/table.ts
|
|
4928
4996
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4929
4997
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4930
|
-
import { Decoration as Decoration10, EditorView as
|
|
4998
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4931
4999
|
var table = (options = {}) => {
|
|
4932
5000
|
return StateField8.define({
|
|
4933
5001
|
create: (state) => update(state, options),
|
|
4934
5002
|
update: (_, tr) => update(tr.state, options),
|
|
4935
|
-
provide: (field) =>
|
|
5003
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4936
5004
|
});
|
|
4937
5005
|
};
|
|
4938
5006
|
var update = (state, _options) => {
|
|
4939
5007
|
const builder = new RangeSetBuilder4();
|
|
4940
|
-
const
|
|
5008
|
+
const cursor = state.selection.main.head;
|
|
4941
5009
|
const tables = [];
|
|
4942
5010
|
const getTable = () => tables[tables.length - 1];
|
|
4943
5011
|
const getRow = () => {
|
|
@@ -4975,7 +5043,7 @@ var update = (state, _options) => {
|
|
|
4975
5043
|
}
|
|
4976
5044
|
});
|
|
4977
5045
|
tables.forEach((table2) => {
|
|
4978
|
-
const replace = state.readOnly ||
|
|
5046
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4979
5047
|
if (replace) {
|
|
4980
5048
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4981
5049
|
block: true,
|
|
@@ -4989,6 +5057,26 @@ var update = (state, _options) => {
|
|
|
4989
5057
|
});
|
|
4990
5058
|
return builder.finish();
|
|
4991
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
|
+
};
|
|
4992
5080
|
var TableWidget = class extends WidgetType6 {
|
|
4993
5081
|
_table;
|
|
4994
5082
|
constructor(_table) {
|
|
@@ -5008,7 +5096,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
5008
5096
|
this._table.header?.forEach((cell) => {
|
|
5009
5097
|
const th = document.createElement("th");
|
|
5010
5098
|
th.setAttribute("class", "cm-table-head");
|
|
5011
|
-
tr.appendChild(th)
|
|
5099
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
5012
5100
|
});
|
|
5013
5101
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
5014
5102
|
this._table.rows?.forEach((row) => {
|
|
@@ -5016,7 +5104,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
5016
5104
|
row.forEach((cell) => {
|
|
5017
5105
|
const td = document.createElement("td");
|
|
5018
5106
|
td.setAttribute("class", "cm-table-cell");
|
|
5019
|
-
tr2.appendChild(td)
|
|
5107
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
5020
5108
|
});
|
|
5021
5109
|
});
|
|
5022
5110
|
return div;
|
|
@@ -5123,10 +5211,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5123
5211
|
class: "cm-code cm-codeblock-line"
|
|
5124
5212
|
});
|
|
5125
5213
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5126
|
-
class:
|
|
5214
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5127
5215
|
});
|
|
5128
5216
|
var fencedCodeLineLast = Decoration11.line({
|
|
5129
|
-
class:
|
|
5217
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5130
5218
|
});
|
|
5131
5219
|
var commentBlockLine = fencedCodeLine;
|
|
5132
5220
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5158,15 +5246,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5158
5246
|
const { state } = view;
|
|
5159
5247
|
const headerLevels = [];
|
|
5160
5248
|
const getHeaderLevels = (node, level) => {
|
|
5161
|
-
invariant4(level > 0, void 0, {
|
|
5162
|
-
F: __dxlog_file12,
|
|
5163
|
-
L: 179,
|
|
5164
|
-
S: void 0,
|
|
5165
|
-
A: [
|
|
5166
|
-
"level > 0",
|
|
5167
|
-
""
|
|
5168
|
-
]
|
|
5169
|
-
});
|
|
5249
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5170
5250
|
if (level > headerLevels.length) {
|
|
5171
5251
|
const len = headerLevels.length;
|
|
5172
5252
|
headerLevels.length = level;
|
|
@@ -5197,15 +5277,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5197
5277
|
listLevels.pop();
|
|
5198
5278
|
};
|
|
5199
5279
|
const getCurrentListLevel = () => {
|
|
5200
|
-
invariant4(listLevels.length, void 0, {
|
|
5201
|
-
F: __dxlog_file12,
|
|
5202
|
-
L: 201,
|
|
5203
|
-
S: void 0,
|
|
5204
|
-
A: [
|
|
5205
|
-
"listLevels.length",
|
|
5206
|
-
""
|
|
5207
|
-
]
|
|
5208
|
-
});
|
|
5280
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5209
5281
|
return listLevels[listLevels.length - 1];
|
|
5210
5282
|
};
|
|
5211
5283
|
const enterNode = (node) => {
|
|
@@ -5243,7 +5315,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5243
5315
|
deco: hide
|
|
5244
5316
|
});
|
|
5245
5317
|
} else {
|
|
5246
|
-
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(".") + "). ";
|
|
5247
5319
|
if (num.length) {
|
|
5248
5320
|
atomicDecoRanges.push({
|
|
5249
5321
|
from: mark.from,
|
|
@@ -5426,11 +5498,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5426
5498
|
}
|
|
5427
5499
|
decoRanges.push({
|
|
5428
5500
|
from: marks[0].to,
|
|
5429
|
-
to: marks[1].from,
|
|
5501
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5430
5502
|
deco: Decoration11.mark({
|
|
5431
5503
|
tagName: "a",
|
|
5432
5504
|
attributes: {
|
|
5433
|
-
class: "cm-link",
|
|
5505
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5434
5506
|
href: url,
|
|
5435
5507
|
rel: "noreferrer",
|
|
5436
5508
|
target: "_blank"
|
|
@@ -5508,18 +5580,21 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5508
5580
|
deco.add(from, to, d);
|
|
5509
5581
|
}
|
|
5510
5582
|
const atomicDeco = new RangeSetBuilder5();
|
|
5511
|
-
for (const { from, to, deco:
|
|
5512
|
-
|
|
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);
|
|
5513
5588
|
}
|
|
5514
5589
|
return {
|
|
5515
5590
|
deco: deco.finish(),
|
|
5516
5591
|
atomicDeco: atomicDeco.finish()
|
|
5517
5592
|
};
|
|
5518
5593
|
};
|
|
5519
|
-
var forceUpdate =
|
|
5594
|
+
var forceUpdate = StateEffect7.define();
|
|
5520
5595
|
var decorateMarkdown = (options = {}) => {
|
|
5521
5596
|
return [
|
|
5522
|
-
|
|
5597
|
+
ViewPlugin15.fromClass(class {
|
|
5523
5598
|
deco;
|
|
5524
5599
|
atomicDeco;
|
|
5525
5600
|
pendingUpdate;
|
|
@@ -5554,9 +5629,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5554
5629
|
}
|
|
5555
5630
|
}, {
|
|
5556
5631
|
provide: (plugin) => [
|
|
5557
|
-
Prec4.low(
|
|
5558
|
-
|
|
5559
|
-
|
|
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)
|
|
5560
5635
|
]
|
|
5561
5636
|
}),
|
|
5562
5637
|
image(),
|
|
@@ -5624,12 +5699,7 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5624
5699
|
(context) => {
|
|
5625
5700
|
log9.info("completion context", {
|
|
5626
5701
|
context
|
|
5627
|
-
}, {
|
|
5628
|
-
F: __dxlog_file13,
|
|
5629
|
-
L: 27,
|
|
5630
|
-
S: void 0,
|
|
5631
|
-
C: (f, a) => f(...a)
|
|
5632
|
-
});
|
|
5702
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5633
5703
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5634
5704
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5635
5705
|
return null;
|
|
@@ -5646,8 +5716,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5646
5716
|
};
|
|
5647
5717
|
|
|
5648
5718
|
// src/extensions/modal.ts
|
|
5649
|
-
import { StateEffect as
|
|
5650
|
-
var modalStateEffect =
|
|
5719
|
+
import { StateEffect as StateEffect8, StateField as StateField9 } from "@codemirror/state";
|
|
5720
|
+
var modalStateEffect = StateEffect8.define();
|
|
5651
5721
|
var modalStateField = StateField9.define({
|
|
5652
5722
|
create: () => false,
|
|
5653
5723
|
update: (value, tr) => {
|
|
@@ -5862,15 +5932,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5862
5932
|
break;
|
|
5863
5933
|
}
|
|
5864
5934
|
case "BulletList": {
|
|
5865
|
-
invariant5(current, void 0, {
|
|
5866
|
-
F: __dxlog_file14,
|
|
5867
|
-
L: 219,
|
|
5868
|
-
S: void 0,
|
|
5869
|
-
A: [
|
|
5870
|
-
"current",
|
|
5871
|
-
""
|
|
5872
|
-
]
|
|
5873
|
-
});
|
|
5935
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5874
5936
|
parent = current;
|
|
5875
5937
|
if (current) {
|
|
5876
5938
|
current.lineRange.to = current.node.from;
|
|
@@ -5879,15 +5941,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5879
5941
|
break;
|
|
5880
5942
|
}
|
|
5881
5943
|
case "ListItem": {
|
|
5882
|
-
invariant5(parent, void 0, {
|
|
5883
|
-
F: __dxlog_file14,
|
|
5884
|
-
L: 228,
|
|
5885
|
-
S: void 0,
|
|
5886
|
-
A: [
|
|
5887
|
-
"parent",
|
|
5888
|
-
""
|
|
5889
|
-
]
|
|
5890
|
-
});
|
|
5944
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5891
5945
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5892
5946
|
const docRange = {
|
|
5893
5947
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5921,42 +5975,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5921
5975
|
break;
|
|
5922
5976
|
}
|
|
5923
5977
|
case "ListMark": {
|
|
5924
|
-
invariant5(current, void 0, {
|
|
5925
|
-
F: __dxlog_file14,
|
|
5926
|
-
L: 272,
|
|
5927
|
-
S: void 0,
|
|
5928
|
-
A: [
|
|
5929
|
-
"current",
|
|
5930
|
-
""
|
|
5931
|
-
]
|
|
5932
|
-
});
|
|
5978
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5933
5979
|
current.type = "bullet";
|
|
5934
5980
|
current.contentRange.from = node.from + "- ".length;
|
|
5935
5981
|
break;
|
|
5936
5982
|
}
|
|
5937
5983
|
case "Task": {
|
|
5938
|
-
invariant5(current, void 0, {
|
|
5939
|
-
F: __dxlog_file14,
|
|
5940
|
-
L: 278,
|
|
5941
|
-
S: void 0,
|
|
5942
|
-
A: [
|
|
5943
|
-
"current",
|
|
5944
|
-
""
|
|
5945
|
-
]
|
|
5946
|
-
});
|
|
5984
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5947
5985
|
current.type = "task";
|
|
5948
5986
|
break;
|
|
5949
5987
|
}
|
|
5950
5988
|
case "TaskMarker": {
|
|
5951
|
-
invariant5(current, void 0, {
|
|
5952
|
-
F: __dxlog_file14,
|
|
5953
|
-
L: 283,
|
|
5954
|
-
S: void 0,
|
|
5955
|
-
A: [
|
|
5956
|
-
"current",
|
|
5957
|
-
""
|
|
5958
|
-
]
|
|
5959
|
-
});
|
|
5989
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5960
5990
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5961
5991
|
break;
|
|
5962
5992
|
}
|
|
@@ -5964,29 +5994,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5964
5994
|
},
|
|
5965
5995
|
leave: (node) => {
|
|
5966
5996
|
if (node.name === "BulletList") {
|
|
5967
|
-
invariant5(parent, void 0, {
|
|
5968
|
-
F: __dxlog_file14,
|
|
5969
|
-
L: 291,
|
|
5970
|
-
S: void 0,
|
|
5971
|
-
A: [
|
|
5972
|
-
"parent",
|
|
5973
|
-
""
|
|
5974
|
-
]
|
|
5975
|
-
});
|
|
5997
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5976
5998
|
prevSiblings[level--] = void 0;
|
|
5977
5999
|
parent = parent.parent;
|
|
5978
6000
|
}
|
|
5979
6001
|
}
|
|
5980
6002
|
});
|
|
5981
|
-
invariant5(tree, void 0, {
|
|
5982
|
-
F: __dxlog_file14,
|
|
5983
|
-
L: 298,
|
|
5984
|
-
S: void 0,
|
|
5985
|
-
A: [
|
|
5986
|
-
"tree",
|
|
5987
|
-
""
|
|
5988
|
-
]
|
|
5989
|
-
});
|
|
6003
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5990
6004
|
return tree;
|
|
5991
6005
|
};
|
|
5992
6006
|
return [
|
|
@@ -6271,17 +6285,17 @@ var commands = () => keymap11.of([
|
|
|
6271
6285
|
|
|
6272
6286
|
// src/extensions/outliner/outliner.ts
|
|
6273
6287
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6274
|
-
import { Decoration as Decoration12, EditorView as
|
|
6275
|
-
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";
|
|
6276
6290
|
|
|
6277
6291
|
// src/extensions/outliner/editor.ts
|
|
6278
6292
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6279
|
-
import { ViewPlugin as
|
|
6293
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6280
6294
|
import { log as log10 } from "@dxos/log";
|
|
6281
6295
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6282
6296
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6283
6297
|
var initialize = () => {
|
|
6284
|
-
return
|
|
6298
|
+
return ViewPlugin16.fromClass(class {
|
|
6285
6299
|
constructor(view) {
|
|
6286
6300
|
const first = view.state.doc.lineAt(0);
|
|
6287
6301
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6428,35 +6442,20 @@ var editor = () => [
|
|
|
6428
6442
|
text: insert.toString(),
|
|
6429
6443
|
length: insert.length
|
|
6430
6444
|
}
|
|
6431
|
-
}, {
|
|
6432
|
-
F: __dxlog_file15,
|
|
6433
|
-
L: 164,
|
|
6434
|
-
S: void 0,
|
|
6435
|
-
C: (f, a) => f(...a)
|
|
6436
|
-
});
|
|
6445
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6437
6446
|
}
|
|
6438
6447
|
});
|
|
6439
6448
|
if (changes.length > 0) {
|
|
6440
6449
|
log10("modified,", {
|
|
6441
6450
|
changes
|
|
6442
|
-
}, {
|
|
6443
|
-
F: __dxlog_file15,
|
|
6444
|
-
L: 175,
|
|
6445
|
-
S: void 0,
|
|
6446
|
-
C: (f, a) => f(...a)
|
|
6447
|
-
});
|
|
6451
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6448
6452
|
return [
|
|
6449
6453
|
{
|
|
6450
6454
|
changes
|
|
6451
6455
|
}
|
|
6452
6456
|
];
|
|
6453
6457
|
} else if (cancel) {
|
|
6454
|
-
log10("cancel", void 0, {
|
|
6455
|
-
F: __dxlog_file15,
|
|
6456
|
-
L: 178,
|
|
6457
|
-
S: void 0,
|
|
6458
|
-
C: (f, a) => f(...a)
|
|
6459
|
-
});
|
|
6458
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6460
6459
|
return [];
|
|
6461
6460
|
}
|
|
6462
6461
|
return tr;
|
|
@@ -6464,10 +6463,10 @@ var editor = () => [
|
|
|
6464
6463
|
];
|
|
6465
6464
|
|
|
6466
6465
|
// src/extensions/outliner/menu.ts
|
|
6467
|
-
import { EditorView as
|
|
6466
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6468
6467
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6469
6468
|
var menu = (options = {}) => [
|
|
6470
|
-
|
|
6469
|
+
ViewPlugin17.fromClass(class {
|
|
6471
6470
|
view;
|
|
6472
6471
|
tag;
|
|
6473
6472
|
rafId;
|
|
@@ -6529,7 +6528,7 @@ var menu = (options = {}) => [
|
|
|
6529
6528
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6530
6529
|
}
|
|
6531
6530
|
}),
|
|
6532
|
-
|
|
6531
|
+
EditorView25.theme({
|
|
6533
6532
|
".cm-popover-trigger": {
|
|
6534
6533
|
position: "fixed",
|
|
6535
6534
|
padding: "0",
|
|
@@ -6565,12 +6564,12 @@ var outliner = (_options = {}) => [
|
|
|
6565
6564
|
listPaddingLeft: 8
|
|
6566
6565
|
}),
|
|
6567
6566
|
// Researve space for menu.
|
|
6568
|
-
|
|
6567
|
+
EditorView26.contentAttributes.of({
|
|
6569
6568
|
class: "w-full !mr-[3rem]"
|
|
6570
6569
|
})
|
|
6571
6570
|
];
|
|
6572
6571
|
var decorations = () => [
|
|
6573
|
-
|
|
6572
|
+
ViewPlugin18.fromClass(class {
|
|
6574
6573
|
decorations = Decoration12.none;
|
|
6575
6574
|
constructor(view) {
|
|
6576
6575
|
this.updateDecorations(view.state, view);
|
|
@@ -6595,7 +6594,7 @@ var decorations = () => [
|
|
|
6595
6594
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6596
6595
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6597
6596
|
decorations2.push(Decoration12.line({
|
|
6598
|
-
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"))
|
|
6599
6598
|
}).range(line.from, line.from));
|
|
6600
6599
|
}
|
|
6601
6600
|
}
|
|
@@ -6605,7 +6604,7 @@ var decorations = () => [
|
|
|
6605
6604
|
decorations: (v) => v.decorations
|
|
6606
6605
|
}),
|
|
6607
6606
|
// Theme.
|
|
6608
|
-
|
|
6607
|
+
EditorView26.theme(Object.assign({
|
|
6609
6608
|
".cm-list-item": {
|
|
6610
6609
|
borderLeftWidth: "1px",
|
|
6611
6610
|
borderRightWidth: "1px",
|
|
@@ -6640,28 +6639,57 @@ var decorations = () => [
|
|
|
6640
6639
|
|
|
6641
6640
|
// src/extensions/preview/preview.ts
|
|
6642
6641
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6643
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
|
|
6644
|
-
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();
|
|
6645
6646
|
var preview = (options = {}) => {
|
|
6647
|
+
const viewRef = {
|
|
6648
|
+
current: void 0
|
|
6649
|
+
};
|
|
6646
6650
|
return [
|
|
6647
6651
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6648
6652
|
// "Block decorations may not be specified via plugins".
|
|
6649
6653
|
StateField11.define({
|
|
6650
|
-
create: (state) => buildDecorations3(state, options),
|
|
6654
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6651
6655
|
update: (decorations2, tr) => {
|
|
6652
|
-
if (tr.docChanged) {
|
|
6653
|
-
return buildDecorations3(tr.state, options);
|
|
6656
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6657
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6654
6658
|
}
|
|
6655
6659
|
return decorations2.map(tr.changes);
|
|
6656
6660
|
},
|
|
6657
6661
|
provide: (field) => [
|
|
6658
|
-
|
|
6659
|
-
|
|
6662
|
+
EditorView27.decorations.from(field),
|
|
6663
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6660
6664
|
]
|
|
6665
|
+
}),
|
|
6666
|
+
ViewPlugin19.define((view) => {
|
|
6667
|
+
viewRef.current = view;
|
|
6668
|
+
return {
|
|
6669
|
+
destroy() {
|
|
6670
|
+
viewRef.current = void 0;
|
|
6671
|
+
}
|
|
6672
|
+
};
|
|
6661
6673
|
})
|
|
6662
6674
|
];
|
|
6663
6675
|
};
|
|
6664
|
-
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) => {
|
|
6665
6693
|
const builder = new RangeSetBuilder6();
|
|
6666
6694
|
syntaxTree10(state).iterate({
|
|
6667
6695
|
enter: (node) => {
|
|
@@ -6673,8 +6701,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6673
6701
|
case "Link": {
|
|
6674
6702
|
const link = getLinkRef(state, node.node);
|
|
6675
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;
|
|
6676
6709
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6677
|
-
widget: new PreviewInlineWidget(options,
|
|
6710
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6678
6711
|
side: 1
|
|
6679
6712
|
}));
|
|
6680
6713
|
}
|
|
@@ -6766,7 +6799,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6766
6799
|
};
|
|
6767
6800
|
|
|
6768
6801
|
// src/extensions/replacer.ts
|
|
6769
|
-
import { EditorView as
|
|
6802
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6770
6803
|
var defaultReplacements = [
|
|
6771
6804
|
{
|
|
6772
6805
|
input: "--",
|
|
@@ -6829,7 +6862,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6829
6862
|
const sortedReplacements = [
|
|
6830
6863
|
...replacements
|
|
6831
6864
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6832
|
-
return
|
|
6865
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6833
6866
|
if (insert.length !== 1) {
|
|
6834
6867
|
return false;
|
|
6835
6868
|
}
|
|
@@ -6863,12 +6896,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6863
6896
|
});
|
|
6864
6897
|
};
|
|
6865
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
|
+
|
|
6866
6956
|
// src/extensions/submit.ts
|
|
6867
6957
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6868
|
-
import { keymap as
|
|
6958
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6869
6959
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6870
6960
|
return [
|
|
6871
|
-
Prec6.highest(
|
|
6961
|
+
Prec6.highest(keymap13.of([
|
|
6872
6962
|
{
|
|
6873
6963
|
key: "Enter",
|
|
6874
6964
|
preventDefault: true,
|
|
@@ -6913,6 +7003,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6913
7003
|
// src/extensions/tags/extended-markdown.ts
|
|
6914
7004
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6915
7005
|
import { parseMixed } from "@lezer/common";
|
|
7006
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6916
7007
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6917
7008
|
return [
|
|
6918
7009
|
createMarkdownExtensions({
|
|
@@ -6924,13 +7015,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6924
7015
|
{
|
|
6925
7016
|
name: "SetextHeading",
|
|
6926
7017
|
parse: () => false
|
|
6927
|
-
}
|
|
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)
|
|
6928
7022
|
]
|
|
6929
7023
|
}
|
|
6930
7024
|
]
|
|
6931
7025
|
})
|
|
6932
7026
|
];
|
|
6933
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
|
+
};
|
|
6934
7077
|
var mixedParser = (registry) => {
|
|
6935
7078
|
const customTags = Object.keys(registry ?? {});
|
|
6936
7079
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6964,219 +7107,793 @@ var mixedParser = (registry) => {
|
|
|
6964
7107
|
});
|
|
6965
7108
|
};
|
|
6966
7109
|
|
|
6967
|
-
// src/extensions/tags/
|
|
6968
|
-
import { StateEffect as
|
|
6969
|
-
import { Decoration as Decoration14, EditorView as
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
var
|
|
6973
|
-
var
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
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) => {
|
|
6984
7133
|
for (const effect of tr.effects) {
|
|
6985
|
-
if (effect.is(
|
|
6986
|
-
|
|
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
|
+
}
|
|
6987
7153
|
}
|
|
6988
7154
|
}
|
|
6989
|
-
if (tr.docChanged) {
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
7155
|
+
if (!tr.docChanged) {
|
|
7156
|
+
log12(expiries);
|
|
7157
|
+
return {
|
|
7158
|
+
decorations: decorations2,
|
|
7159
|
+
expiries,
|
|
7160
|
+
batchStart
|
|
7161
|
+
};
|
|
7162
|
+
}
|
|
7163
|
+
let isReset = tr.state.doc.length === 0;
|
|
7164
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7165
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7166
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7167
|
+
isReset = true;
|
|
7168
|
+
}
|
|
7169
|
+
});
|
|
7170
|
+
}
|
|
7171
|
+
if (isReset) {
|
|
7172
|
+
log12([]);
|
|
7173
|
+
return {
|
|
7174
|
+
decorations: Decoration14.none,
|
|
7175
|
+
expiries: [],
|
|
7176
|
+
batchStart: 0
|
|
7177
|
+
};
|
|
7178
|
+
}
|
|
7179
|
+
const now = Date.now();
|
|
7180
|
+
const add = [];
|
|
7181
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
7182
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
7183
|
+
add.push({
|
|
7184
|
+
from: fromB,
|
|
7185
|
+
to: toB
|
|
7186
|
+
});
|
|
7187
|
+
}
|
|
7188
|
+
});
|
|
7189
|
+
if (add.length > 0) {
|
|
7190
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
7191
|
+
if (canCoalesce) {
|
|
7192
|
+
let lastFrom = -1;
|
|
7193
|
+
let lastTo = -1;
|
|
7194
|
+
decorations2.between(0, tr.state.doc.length, (from, to) => {
|
|
7195
|
+
lastFrom = from;
|
|
7196
|
+
lastTo = to;
|
|
7197
|
+
});
|
|
7198
|
+
if (lastFrom >= 0) {
|
|
7199
|
+
decorations2 = decorations2.update({
|
|
7200
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo)
|
|
7201
|
+
});
|
|
7202
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
7203
|
+
const mergedTo = add[add.length - 1].to;
|
|
7204
|
+
decorations2 = decorations2.update({
|
|
7205
|
+
add: [
|
|
7206
|
+
Decoration14.mark({
|
|
7207
|
+
class: "cm-fader"
|
|
7208
|
+
}).range(mergedFrom, mergedTo)
|
|
7209
|
+
]
|
|
7210
|
+
});
|
|
7211
|
+
expiries = [
|
|
7212
|
+
...expiries.slice(0, -1),
|
|
7213
|
+
now + removalDelay
|
|
7214
|
+
];
|
|
7215
|
+
}
|
|
7216
|
+
} else {
|
|
7217
|
+
batchStart = now;
|
|
7218
|
+
expiries = [
|
|
7219
|
+
...expiries,
|
|
7220
|
+
now + removalDelay
|
|
7221
|
+
];
|
|
7222
|
+
decorations2 = decorations2.update({
|
|
7223
|
+
add: add.map(({ from, to }) => Decoration14.mark({
|
|
7224
|
+
class: "cm-fader"
|
|
7225
|
+
}).range(from, to))
|
|
7226
|
+
});
|
|
7227
|
+
}
|
|
7228
|
+
}
|
|
7229
|
+
log12(expiries);
|
|
7230
|
+
return {
|
|
7231
|
+
decorations: decorations2,
|
|
7232
|
+
expiries,
|
|
7233
|
+
batchStart
|
|
7234
|
+
};
|
|
7235
|
+
},
|
|
7236
|
+
provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
|
|
7237
|
+
});
|
|
7238
|
+
const cleanup = ViewPlugin20.fromClass(class {
|
|
7239
|
+
view;
|
|
7240
|
+
#timer;
|
|
7241
|
+
constructor(view) {
|
|
7242
|
+
this.view = view;
|
|
7243
|
+
this.#schedule();
|
|
7244
|
+
}
|
|
7245
|
+
update() {
|
|
7246
|
+
this.#schedule();
|
|
7247
|
+
}
|
|
7248
|
+
#schedule() {
|
|
7249
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
7250
|
+
if (expiries.length === 0) {
|
|
7251
|
+
clearTimeout(this.#timer);
|
|
7252
|
+
this.#timer = void 0;
|
|
7253
|
+
return;
|
|
7254
|
+
}
|
|
7255
|
+
if (this.#timer !== void 0) {
|
|
7256
|
+
return;
|
|
7257
|
+
}
|
|
7258
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
7259
|
+
this.#timer = setTimeout(() => {
|
|
7260
|
+
this.#timer = void 0;
|
|
7261
|
+
this.view.dispatch({
|
|
7262
|
+
effects: dequeue.of(Date.now())
|
|
7263
|
+
});
|
|
7264
|
+
}, delay);
|
|
7265
|
+
}
|
|
7266
|
+
destroy() {
|
|
7267
|
+
clearTimeout(this.#timer);
|
|
7268
|
+
}
|
|
7269
|
+
});
|
|
7270
|
+
return [
|
|
7271
|
+
fadeField,
|
|
7272
|
+
cleanup,
|
|
7273
|
+
EditorView29.theme({
|
|
7274
|
+
".cm-fader": {
|
|
7275
|
+
animation: "fader 1s ease-out forwards"
|
|
7276
|
+
},
|
|
7277
|
+
"@keyframes fader": {
|
|
7278
|
+
"0%": {
|
|
7279
|
+
textShadow: "0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)"
|
|
7280
|
+
},
|
|
7281
|
+
"100%": {}
|
|
7282
|
+
}
|
|
7283
|
+
})
|
|
7284
|
+
];
|
|
7285
|
+
};
|
|
7286
|
+
|
|
7287
|
+
// src/extensions/tags/typewriter.ts
|
|
7288
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7289
|
+
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7290
|
+
import { Domino as Domino3 } from "@dxos/ui";
|
|
7291
|
+
var typewriterBypass = Annotation3.define();
|
|
7292
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7293
|
+
var CURSOR_LINGER = 3e3;
|
|
7294
|
+
var FRAME_BUDGET_MS = 4;
|
|
7295
|
+
var CHARS_PER_FRAME = 5;
|
|
7296
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7297
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7298
|
+
var typewriter = (options = {}) => {
|
|
7299
|
+
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7300
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7301
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7302
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7303
|
+
const suppressAppend = StateEffect11.define();
|
|
7304
|
+
const insertChunk = StateEffect11.define();
|
|
7305
|
+
const bufferField = StateField13.define({
|
|
7306
|
+
create: () => ({
|
|
7307
|
+
text: "",
|
|
7308
|
+
head: 0,
|
|
7309
|
+
insertAt: 0
|
|
7310
|
+
}),
|
|
7311
|
+
update: (value, tr) => {
|
|
7312
|
+
let { text, head, insertAt } = value;
|
|
7313
|
+
for (const effect of tr.effects) {
|
|
7314
|
+
if (effect.is(suppressAppend)) {
|
|
7315
|
+
if (text.length === head) {
|
|
7316
|
+
insertAt = effect.value.from;
|
|
7317
|
+
}
|
|
7318
|
+
text += effect.value.text;
|
|
7319
|
+
}
|
|
7320
|
+
if (effect.is(insertChunk)) {
|
|
7321
|
+
head += effect.value.text.length;
|
|
7322
|
+
insertAt = effect.value.from + effect.value.text.length;
|
|
7323
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7324
|
+
text = text.slice(head);
|
|
7325
|
+
head = 0;
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
}
|
|
7329
|
+
if (tr.docChanged) {
|
|
7330
|
+
let isReset = tr.state.doc.length === 0;
|
|
7331
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7332
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7333
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7334
|
+
isReset = true;
|
|
7335
|
+
}
|
|
7336
|
+
});
|
|
7337
|
+
}
|
|
7338
|
+
if (isReset) {
|
|
7339
|
+
return {
|
|
7340
|
+
text: "",
|
|
7341
|
+
head: 0,
|
|
7342
|
+
insertAt: 0
|
|
7343
|
+
};
|
|
7344
|
+
}
|
|
7345
|
+
if (!tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7346
|
+
insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));
|
|
7347
|
+
}
|
|
7348
|
+
}
|
|
7349
|
+
return {
|
|
7350
|
+
text,
|
|
7351
|
+
head,
|
|
7352
|
+
insertAt
|
|
7353
|
+
};
|
|
6993
7354
|
}
|
|
6994
7355
|
});
|
|
6995
|
-
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 {
|
|
6996
7388
|
view;
|
|
6997
|
-
|
|
7389
|
+
_raf;
|
|
7390
|
+
_activeStreamTag = null;
|
|
6998
7391
|
constructor(view) {
|
|
6999
7392
|
this.view = view;
|
|
7000
7393
|
}
|
|
7001
7394
|
update(update2) {
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
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();
|
|
7009
7402
|
}
|
|
7010
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
|
+
};
|
|
7011
7478
|
destroy() {
|
|
7012
|
-
|
|
7479
|
+
if (this._raf !== void 0) {
|
|
7480
|
+
cancelAnimationFrame(this._raf);
|
|
7481
|
+
}
|
|
7013
7482
|
}
|
|
7014
7483
|
});
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
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
|
+
}
|
|
7021
7525
|
}
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
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({
|
|
7025
7541
|
widget: new CursorWidget(),
|
|
7026
7542
|
side: 1
|
|
7027
|
-
}).range(
|
|
7543
|
+
}).range(pos)
|
|
7028
7544
|
]);
|
|
7029
7545
|
},
|
|
7030
|
-
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
|
+
}
|
|
7031
7573
|
});
|
|
7032
7574
|
return [
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7575
|
+
visibilityField,
|
|
7576
|
+
decorationField,
|
|
7577
|
+
timerPlugin
|
|
7036
7578
|
];
|
|
7037
7579
|
};
|
|
7038
|
-
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
|
+
}
|
|
7039
7586
|
toDOM() {
|
|
7040
|
-
const inner = Domino3.of("span").text("\
|
|
7041
|
-
animation: "blink
|
|
7587
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7588
|
+
animation: "blink 1s infinite",
|
|
7589
|
+
animationDelay: "250ms"
|
|
7042
7590
|
});
|
|
7043
7591
|
return Domino3.of("span").style({
|
|
7044
7592
|
opacity: "0.8"
|
|
7045
|
-
}).
|
|
7593
|
+
}).append(inner).root;
|
|
7046
7594
|
}
|
|
7047
7595
|
};
|
|
7048
|
-
var
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
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
|
+
};
|
|
7067
7632
|
}
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
isReset = true;
|
|
7073
|
-
}
|
|
7074
|
-
});
|
|
7633
|
+
if (buffer[close - 1] === "/") {
|
|
7634
|
+
return {
|
|
7635
|
+
count: close + 1 - start
|
|
7636
|
+
};
|
|
7075
7637
|
}
|
|
7076
|
-
|
|
7077
|
-
|
|
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;
|
|
7078
7693
|
}
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
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") {
|
|
7082
7739
|
return;
|
|
7083
7740
|
}
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
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;
|
|
7088
7746
|
}
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
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;
|
|
7100
7778
|
constructor(view) {
|
|
7101
|
-
this.
|
|
7779
|
+
this.decorations = buildDecorations5(view);
|
|
7102
7780
|
}
|
|
7103
7781
|
update(update2) {
|
|
7104
|
-
if (
|
|
7105
|
-
|
|
7782
|
+
if (update2.docChanged) {
|
|
7783
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7106
7784
|
}
|
|
7107
|
-
|
|
7108
|
-
|
|
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));
|
|
7109
7831
|
return;
|
|
7110
7832
|
}
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
|
|
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
|
+
}
|
|
7114
7850
|
}
|
|
7115
|
-
const totalDelay = FADE_IN_DURATION + removalDelay;
|
|
7116
|
-
const id = setTimeout(() => {
|
|
7117
|
-
this.view.dispatch({
|
|
7118
|
-
effects: removeDecoration.of({
|
|
7119
|
-
from: fromB,
|
|
7120
|
-
to: toB
|
|
7121
|
-
})
|
|
7122
|
-
});
|
|
7123
|
-
this._timers.delete(key);
|
|
7124
|
-
}, totalDelay);
|
|
7125
|
-
this._timers.set(key, id);
|
|
7126
|
-
});
|
|
7127
|
-
}
|
|
7128
|
-
destroy() {
|
|
7129
|
-
for (const id of this._timers.values()) {
|
|
7130
|
-
clearTimeout(id);
|
|
7131
7851
|
}
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
}
|
|
7852
|
+
});
|
|
7853
|
+
return Decoration17.set(ranges, true);
|
|
7854
|
+
};
|
|
7135
7855
|
return [
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
},
|
|
7145
|
-
"@keyframes fade-in": {
|
|
7146
|
-
"0%": {
|
|
7147
|
-
opacity: "0"
|
|
7148
|
-
},
|
|
7149
|
-
"80%": {
|
|
7150
|
-
opacity: "1"
|
|
7151
|
-
},
|
|
7152
|
-
"100%": {
|
|
7153
|
-
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);
|
|
7154
7864
|
}
|
|
7155
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": {}
|
|
7156
7880
|
})
|
|
7157
7881
|
];
|
|
7158
7882
|
};
|
|
7159
7883
|
|
|
7160
7884
|
// src/extensions/tags/xml-tags.ts
|
|
7161
7885
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7162
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7163
|
-
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";
|
|
7164
7888
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7165
7889
|
import { log as log11 } from "@dxos/log";
|
|
7890
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7166
7891
|
|
|
7167
7892
|
// src/extensions/tags/xml-util.ts
|
|
7168
7893
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7169
7894
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7170
7895
|
var nodeToJson = (state, node) => {
|
|
7171
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7172
|
-
F: __dxlog_file16,
|
|
7173
|
-
L: 18,
|
|
7174
|
-
S: void 0,
|
|
7175
|
-
A: [
|
|
7176
|
-
"node.type.name === 'Element'",
|
|
7177
|
-
"'Node is not an Element'"
|
|
7178
|
-
]
|
|
7179
|
-
});
|
|
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'"] });
|
|
7180
7897
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7181
7898
|
if (openTag) {
|
|
7182
7899
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7208,13 +7925,23 @@ var nodeToJson = (state, node) => {
|
|
|
7208
7925
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7209
7926
|
const children = [];
|
|
7210
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
|
+
};
|
|
7211
7939
|
while (child) {
|
|
7212
7940
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7213
7941
|
if (child.type.name === "Text") {
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
}
|
|
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)));
|
|
7218
7945
|
} else if (child.type.name === "Element") {
|
|
7219
7946
|
const data = nodeToJson(state, child);
|
|
7220
7947
|
if (data) {
|
|
@@ -7224,26 +7951,63 @@ var nodeToJson = (state, node) => {
|
|
|
7224
7951
|
}
|
|
7225
7952
|
child = child.nextSibling;
|
|
7226
7953
|
}
|
|
7954
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7955
|
+
children[0] = children[0].trimStart();
|
|
7956
|
+
}
|
|
7227
7957
|
if (children.length > 0) {
|
|
7228
|
-
|
|
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;
|
|
7229
7967
|
}
|
|
7230
7968
|
}
|
|
7231
7969
|
return tag;
|
|
7232
7970
|
}
|
|
7233
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
|
+
};
|
|
7234
7996
|
|
|
7235
7997
|
// src/extensions/tags/xml-tags.ts
|
|
7236
7998
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
7237
|
-
var navigatePreviousEffect =
|
|
7238
|
-
var navigateNextEffect =
|
|
7999
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8000
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7239
8001
|
var getXmlTextChild = (children) => {
|
|
7240
8002
|
const child = children?.[0];
|
|
7241
8003
|
return typeof child === "string" ? child : null;
|
|
7242
8004
|
};
|
|
7243
|
-
var
|
|
7244
|
-
var
|
|
7245
|
-
var
|
|
7246
|
-
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({
|
|
7247
8011
|
create: () => void 0,
|
|
7248
8012
|
update: (value, tr) => {
|
|
7249
8013
|
for (const effect of tr.effects) {
|
|
@@ -7254,7 +8018,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7254
8018
|
return value;
|
|
7255
8019
|
}
|
|
7256
8020
|
});
|
|
7257
|
-
var widgetStateMapStateField =
|
|
8021
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7258
8022
|
create: () => ({}),
|
|
7259
8023
|
update: (map, tr) => {
|
|
7260
8024
|
for (const effect of tr.effects) {
|
|
@@ -7266,12 +8030,7 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7266
8030
|
log11("widget updated", {
|
|
7267
8031
|
id,
|
|
7268
8032
|
value
|
|
7269
|
-
}, {
|
|
7270
|
-
F: __dxlog_file17,
|
|
7271
|
-
L: 153,
|
|
7272
|
-
S: void 0,
|
|
7273
|
-
C: (f, a) => f(...a)
|
|
7274
|
-
});
|
|
8033
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7275
8034
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7276
8035
|
return {
|
|
7277
8036
|
...map,
|
|
@@ -7301,12 +8060,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7301
8060
|
log11("widget mounted", {
|
|
7302
8061
|
id: state.id,
|
|
7303
8062
|
tag: state.props._tag
|
|
7304
|
-
}, {
|
|
7305
|
-
F: __dxlog_file17,
|
|
7306
|
-
L: 206,
|
|
7307
|
-
S: void 0,
|
|
7308
|
-
C: (f, a) => f(...a)
|
|
7309
|
-
});
|
|
8063
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7310
8064
|
widgets.set(state.id, state);
|
|
7311
8065
|
setWidgets?.([
|
|
7312
8066
|
...widgets.values()
|
|
@@ -7317,12 +8071,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7317
8071
|
log11("widget unmounted", {
|
|
7318
8072
|
id,
|
|
7319
8073
|
tag: state?.props._tag
|
|
7320
|
-
}, {
|
|
7321
|
-
F: __dxlog_file17,
|
|
7322
|
-
L: 212,
|
|
7323
|
-
S: void 0,
|
|
7324
|
-
C: (f, a) => f(...a)
|
|
7325
|
-
});
|
|
8074
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7326
8075
|
widgets.delete(id);
|
|
7327
8076
|
setWidgets?.([
|
|
7328
8077
|
...widgets.values()
|
|
@@ -7331,7 +8080,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7331
8080
|
};
|
|
7332
8081
|
return notifier;
|
|
7333
8082
|
};
|
|
7334
|
-
var keyHandlers =
|
|
8083
|
+
var keyHandlers = keymap14.of([
|
|
7335
8084
|
{
|
|
7336
8085
|
key: "Mod-ArrowUp",
|
|
7337
8086
|
run: (view) => {
|
|
@@ -7352,7 +8101,7 @@ var keyHandlers = keymap13.of([
|
|
|
7352
8101
|
}
|
|
7353
8102
|
]);
|
|
7354
8103
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7355
|
-
return
|
|
8104
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7356
8105
|
update2.transactions.forEach((transaction) => {
|
|
7357
8106
|
for (const effect of transaction.effects) {
|
|
7358
8107
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7437,7 +8186,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7437
8186
|
});
|
|
7438
8187
|
});
|
|
7439
8188
|
};
|
|
7440
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8189
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7441
8190
|
update(update2) {
|
|
7442
8191
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7443
8192
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7464,14 +8213,14 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7464
8213
|
}
|
|
7465
8214
|
}
|
|
7466
8215
|
});
|
|
7467
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8216
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7468
8217
|
create: (state) => {
|
|
7469
8218
|
return buildDecorations4(state, {
|
|
7470
8219
|
from: 0,
|
|
7471
8220
|
to: state.doc.length
|
|
7472
8221
|
}, registry, notifier);
|
|
7473
8222
|
},
|
|
7474
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8223
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7475
8224
|
for (const effect of tr.effects) {
|
|
7476
8225
|
if (effect.is(xmlTagResetEffect)) {
|
|
7477
8226
|
if (tr.docChanged) {
|
|
@@ -7482,7 +8231,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7482
8231
|
}
|
|
7483
8232
|
return {
|
|
7484
8233
|
from: 0,
|
|
7485
|
-
decorations:
|
|
8234
|
+
decorations: Decoration18.none
|
|
7486
8235
|
};
|
|
7487
8236
|
}
|
|
7488
8237
|
}
|
|
@@ -7493,24 +8242,23 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7493
8242
|
log11("document reset", {
|
|
7494
8243
|
from,
|
|
7495
8244
|
to: state.doc.length
|
|
7496
|
-
}, {
|
|
7497
|
-
F: __dxlog_file17,
|
|
7498
|
-
L: 374,
|
|
7499
|
-
S: void 0,
|
|
7500
|
-
C: (f, a) => f(...a)
|
|
7501
|
-
});
|
|
8245
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7502
8246
|
return buildDecorations4(state, {
|
|
7503
8247
|
from: 0,
|
|
7504
8248
|
to: state.doc.length
|
|
7505
8249
|
}, registry, notifier);
|
|
7506
8250
|
} else {
|
|
8251
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7507
8252
|
const result = buildDecorations4(state, {
|
|
7508
|
-
from,
|
|
8253
|
+
from: rebuildFrom,
|
|
7509
8254
|
to: state.doc.length
|
|
7510
8255
|
}, registry, notifier);
|
|
7511
8256
|
return {
|
|
7512
8257
|
from: result.from,
|
|
8258
|
+
streamingFrom: result.streamingFrom,
|
|
7513
8259
|
decorations: decorations2.update({
|
|
8260
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8261
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7514
8262
|
add: decorationSetToArray(result.decorations)
|
|
7515
8263
|
})
|
|
7516
8264
|
};
|
|
@@ -7518,12 +8266,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7518
8266
|
}
|
|
7519
8267
|
return {
|
|
7520
8268
|
from,
|
|
8269
|
+
streamingFrom,
|
|
7521
8270
|
decorations: decorations2
|
|
7522
8271
|
};
|
|
7523
8272
|
},
|
|
7524
8273
|
provide: (field) => [
|
|
7525
|
-
|
|
7526
|
-
|
|
8274
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8275
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7527
8276
|
]
|
|
7528
8277
|
});
|
|
7529
8278
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7534,10 +8283,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7534
8283
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7535
8284
|
return {
|
|
7536
8285
|
from: range.from,
|
|
7537
|
-
decorations:
|
|
8286
|
+
decorations: Decoration18.none
|
|
7538
8287
|
};
|
|
7539
8288
|
}
|
|
7540
8289
|
let last = range.from;
|
|
8290
|
+
let streamingFrom;
|
|
7541
8291
|
tree.iterate({
|
|
7542
8292
|
from: range.from,
|
|
7543
8293
|
to: range.to,
|
|
@@ -7550,21 +8300,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7550
8300
|
if (args) {
|
|
7551
8301
|
const def = registry[args._tag];
|
|
7552
8302
|
if (def) {
|
|
8303
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8304
|
+
return false;
|
|
8305
|
+
}
|
|
7553
8306
|
const { block, factory, Component } = def;
|
|
7554
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7555
8307
|
const nodeRange = {
|
|
7556
8308
|
from: node.node.from,
|
|
7557
8309
|
to: node.node.to
|
|
7558
8310
|
};
|
|
8311
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8312
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7559
8313
|
const props = {
|
|
7560
|
-
|
|
8314
|
+
id: widgetId,
|
|
7561
8315
|
range: nodeRange,
|
|
8316
|
+
context,
|
|
7562
8317
|
...args,
|
|
7563
8318
|
...widgetState
|
|
7564
8319
|
};
|
|
7565
|
-
const widget = factory ? factory(props) : Component ?
|
|
8320
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7566
8321
|
if (widget) {
|
|
7567
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8322
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7568
8323
|
widget,
|
|
7569
8324
|
block,
|
|
7570
8325
|
atomic: true,
|
|
@@ -7576,20 +8331,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7576
8331
|
}
|
|
7577
8332
|
}
|
|
7578
8333
|
} catch (err) {
|
|
7579
|
-
log11.catch(err, void 0, {
|
|
7580
|
-
F: __dxlog_file17,
|
|
7581
|
-
L: 459,
|
|
7582
|
-
S: void 0,
|
|
7583
|
-
C: (f, a) => f(...a)
|
|
7584
|
-
});
|
|
8334
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7585
8335
|
}
|
|
7586
8336
|
return false;
|
|
7587
8337
|
}
|
|
7588
8338
|
}
|
|
7589
8339
|
}
|
|
7590
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
|
+
}
|
|
7591
8397
|
return {
|
|
7592
8398
|
from: last,
|
|
8399
|
+
streamingFrom,
|
|
7593
8400
|
decorations: builder.finish()
|
|
7594
8401
|
};
|
|
7595
8402
|
};
|
|
@@ -7598,108 +8405,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7598
8405
|
Component;
|
|
7599
8406
|
props;
|
|
7600
8407
|
notifier;
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
S: this,
|
|
7608
|
-
A: [
|
|
7609
|
-
"id",
|
|
7610
|
-
""
|
|
7611
|
-
]
|
|
7612
|
-
});
|
|
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", ""] });
|
|
7613
8414
|
}
|
|
7614
8415
|
get root() {
|
|
7615
|
-
return this
|
|
8416
|
+
return this.#root;
|
|
7616
8417
|
}
|
|
7617
8418
|
eq(other) {
|
|
8419
|
+
if (this.streaming) {
|
|
8420
|
+
return false;
|
|
8421
|
+
}
|
|
7618
8422
|
return this.id === other.id;
|
|
7619
8423
|
}
|
|
7620
8424
|
ignoreEvent() {
|
|
7621
8425
|
return true;
|
|
7622
8426
|
}
|
|
7623
|
-
toDOM(
|
|
7624
|
-
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
|
+
});
|
|
7625
8446
|
this.notifier.mounted({
|
|
7626
8447
|
id: this.id,
|
|
7627
|
-
root: this
|
|
7628
|
-
props
|
|
8448
|
+
root: this.#root,
|
|
8449
|
+
props,
|
|
7629
8450
|
Component: this.Component
|
|
7630
8451
|
});
|
|
7631
|
-
return
|
|
8452
|
+
return true;
|
|
7632
8453
|
}
|
|
7633
8454
|
destroy(_dom) {
|
|
7634
8455
|
this.notifier.unmounted(this.id);
|
|
7635
|
-
this
|
|
8456
|
+
this.#root = null;
|
|
8457
|
+
this.#view = void 0;
|
|
7636
8458
|
}
|
|
7637
8459
|
};
|
|
7638
|
-
|
|
7639
|
-
// src/extensions/typewriter.ts
|
|
7640
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
7641
|
-
var defaultItems = [
|
|
7642
|
-
"hello world!",
|
|
7643
|
-
"this is a test.",
|
|
7644
|
-
"this is [DXOS](https://dxos.org)"
|
|
7645
|
-
];
|
|
7646
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7647
|
-
let t;
|
|
7648
|
-
let idx = 0;
|
|
7649
|
-
return [
|
|
7650
|
-
keymap14.of([
|
|
7651
|
-
{
|
|
7652
|
-
// Reset.
|
|
7653
|
-
key: "alt-meta-'",
|
|
7654
|
-
run: () => {
|
|
7655
|
-
clearTimeout(t);
|
|
7656
|
-
idx = 0;
|
|
7657
|
-
return true;
|
|
7658
|
-
}
|
|
7659
|
-
},
|
|
7660
|
-
{
|
|
7661
|
-
// Next prompt.
|
|
7662
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
7663
|
-
key: "Shift-Meta-'",
|
|
7664
|
-
run: (view) => {
|
|
7665
|
-
clearTimeout(t);
|
|
7666
|
-
const text = items[idx++];
|
|
7667
|
-
if (idx === items?.length) {
|
|
7668
|
-
idx = 0;
|
|
7669
|
-
}
|
|
7670
|
-
let i = 0;
|
|
7671
|
-
const insert = (d = 0) => {
|
|
7672
|
-
t = setTimeout(() => {
|
|
7673
|
-
const pos = view.state.selection.main.head;
|
|
7674
|
-
view.dispatch({
|
|
7675
|
-
changes: {
|
|
7676
|
-
from: pos,
|
|
7677
|
-
insert: text[i++]
|
|
7678
|
-
},
|
|
7679
|
-
selection: {
|
|
7680
|
-
anchor: pos + 1
|
|
7681
|
-
}
|
|
7682
|
-
});
|
|
7683
|
-
if (i < text.length) {
|
|
7684
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
7685
|
-
}
|
|
7686
|
-
}, d);
|
|
7687
|
-
};
|
|
7688
|
-
insert();
|
|
7689
|
-
return true;
|
|
7690
|
-
}
|
|
7691
|
-
}
|
|
7692
|
-
])
|
|
7693
|
-
];
|
|
7694
|
-
};
|
|
7695
8460
|
export {
|
|
7696
8461
|
Cursor,
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
EditorState3 as EditorState,
|
|
7700
|
-
EditorView30 as EditorView,
|
|
7701
|
-
EditorViewMode,
|
|
7702
|
-
EditorViewModes,
|
|
8462
|
+
EditorState4 as EditorState,
|
|
8463
|
+
EditorView33 as EditorView,
|
|
7703
8464
|
Inline,
|
|
7704
8465
|
InputModeExtensions,
|
|
7705
8466
|
List,
|
|
@@ -7716,6 +8477,7 @@ export {
|
|
|
7716
8477
|
addStyle,
|
|
7717
8478
|
annotations,
|
|
7718
8479
|
autoScroll,
|
|
8480
|
+
autoScrollEffect,
|
|
7719
8481
|
autocomplete,
|
|
7720
8482
|
automerge,
|
|
7721
8483
|
awareness,
|
|
@@ -7729,6 +8491,7 @@ export {
|
|
|
7729
8491
|
commentClickedEffect,
|
|
7730
8492
|
comments,
|
|
7731
8493
|
commentsState,
|
|
8494
|
+
compactSlots,
|
|
7732
8495
|
convertTreeToJson,
|
|
7733
8496
|
createBasicExtensions,
|
|
7734
8497
|
createComment,
|
|
@@ -7752,12 +8515,12 @@ export {
|
|
|
7752
8515
|
defaultThemeSlots,
|
|
7753
8516
|
deleteItem,
|
|
7754
8517
|
documentId,
|
|
8518
|
+
documentSlots,
|
|
7755
8519
|
dropFile,
|
|
8520
|
+
editorClassNames,
|
|
7756
8521
|
editorInputMode,
|
|
7757
|
-
editorSlots,
|
|
7758
|
-
editorWidth,
|
|
7759
|
-
editorWithToolbarLayout,
|
|
7760
8522
|
extendedMarkdown,
|
|
8523
|
+
fader,
|
|
7761
8524
|
filterChars,
|
|
7762
8525
|
flattenRect,
|
|
7763
8526
|
focus,
|
|
@@ -7793,6 +8556,7 @@ export {
|
|
|
7793
8556
|
markdownTagsExtensions,
|
|
7794
8557
|
matchCompletion,
|
|
7795
8558
|
mention,
|
|
8559
|
+
mobileSlots,
|
|
7796
8560
|
modalStateEffect,
|
|
7797
8561
|
modalStateField,
|
|
7798
8562
|
moveItemDown,
|
|
@@ -7812,6 +8576,7 @@ export {
|
|
|
7812
8576
|
removeList,
|
|
7813
8577
|
removeStyle,
|
|
7814
8578
|
replacer,
|
|
8579
|
+
scrollPastEnd,
|
|
7815
8580
|
scrollThreadIntoView,
|
|
7816
8581
|
scrollToLine,
|
|
7817
8582
|
scroller,
|
|
@@ -7824,9 +8589,8 @@ export {
|
|
|
7824
8589
|
setSelection,
|
|
7825
8590
|
setStyle,
|
|
7826
8591
|
singleValueFacet,
|
|
7827
|
-
|
|
8592
|
+
snippets2 as snippets,
|
|
7828
8593
|
staticCompletion,
|
|
7829
|
-
streamer,
|
|
7830
8594
|
submit,
|
|
7831
8595
|
tabbable,
|
|
7832
8596
|
table,
|
|
@@ -7845,7 +8609,12 @@ export {
|
|
|
7845
8609
|
treeFacet,
|
|
7846
8610
|
typeahead,
|
|
7847
8611
|
typewriter,
|
|
8612
|
+
typewriterBypass,
|
|
8613
|
+
typewriterDrainingEffect,
|
|
7848
8614
|
wrapWithCatch,
|
|
8615
|
+
xmlBlockDecoration,
|
|
8616
|
+
xmlElementLength,
|
|
8617
|
+
xmlFormatting,
|
|
7849
8618
|
xmlTagContextEffect,
|
|
7850
8619
|
xmlTagResetEffect,
|
|
7851
8620
|
xmlTagUpdateEffect,
|