@dxos/react-ui-editor 0.3.11-main.508f304 → 0.3.11-main.514e6e4
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 +665 -791
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -2
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness.d.ts +1 -3
- package/dist/types/src/extensions/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/basic.d.ts +2 -2
- package/dist/types/src/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +3 -3
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +0 -7
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +2 -2
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/code.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/heading.d.ts +6 -0
- package/dist/types/src/extensions/markdown/heading.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/hr.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +7 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/tasklist.d.ts.map +1 -0
- package/dist/types/src/hooks/awareness-provider.d.ts +7 -4
- package/dist/types/src/hooks/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/hooks/defs.d.ts +1 -4
- package/dist/types/src/hooks/defs.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +17 -0
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/styles/markdown.d.ts +2 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +24 -27
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +6 -4
- package/src/components/TextEditor/TextEditor.tsx +12 -15
- package/src/components/TextEditor/comments.stories.tsx +5 -5
- package/src/extensions/awareness.ts +14 -31
- package/src/extensions/basic.ts +3 -3
- package/src/extensions/comments.ts +15 -15
- package/src/extensions/index.ts +0 -7
- package/src/extensions/markdown/bundle.ts +3 -7
- package/src/extensions/markdown/code.ts +127 -0
- package/src/extensions/markdown/heading.ts +59 -0
- package/src/extensions/markdown/highlight.ts +9 -15
- package/src/extensions/{hr.ts → markdown/hr.ts} +3 -4
- package/src/extensions/markdown/index.ts +7 -0
- package/src/extensions/{link.ts → markdown/link.ts} +1 -2
- package/src/extensions/{tasklist.ts → markdown/tasklist.ts} +2 -3
- package/src/hooks/awareness-provider.ts +24 -20
- package/src/hooks/defs.ts +1 -6
- package/src/hooks/index.ts +1 -2
- package/src/hooks/useTextEditor.ts +29 -0
- package/src/hooks/useTextModel.ts +46 -12
- package/src/styles/markdown.ts +9 -10
- package/src/themes/default.ts +0 -2
- package/dist/types/src/components/TextEditor/codemirror.stories.d.ts +0 -12
- package/dist/types/src/components/TextEditor/codemirror.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts +0 -12
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/code.d.ts.map +0 -1
- package/dist/types/src/extensions/hr.d.ts.map +0 -1
- package/dist/types/src/extensions/image.d.ts.map +0 -1
- package/dist/types/src/extensions/link.d.ts.map +0 -1
- package/dist/types/src/extensions/table.d.ts.map +0 -1
- package/dist/types/src/extensions/tasklist.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/cursor.d.ts +0 -4
- package/dist/types/src/extensions/yjs/cursor.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/index.d.ts +0 -2
- package/dist/types/src/extensions/yjs/index.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/yjs.d.ts +0 -4
- package/dist/types/src/extensions/yjs/yjs.d.ts.map +0 -1
- package/dist/types/src/extensions/yjs/yjs.test.d.ts +0 -2
- package/dist/types/src/extensions/yjs/yjs.test.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge.d.ts +0 -4
- package/dist/types/src/hooks/automerge.d.ts.map +0 -1
- package/dist/types/src/hooks/yjs.d.ts +0 -28
- package/dist/types/src/hooks/yjs.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts +0 -3
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/dist/types/src/testing/proto/gen/schema.d.ts +0 -15
- package/dist/types/src/testing/proto/gen/schema.d.ts.map +0 -1
- package/dist/types/src/testing/proto/index.d.ts +0 -2
- package/dist/types/src/testing/proto/index.d.ts.map +0 -1
- package/dist/types/src/testing/replicator.d.ts +0 -45
- package/dist/types/src/testing/replicator.d.ts.map +0 -1
- package/src/components/TextEditor/codemirror.stories.ts +0 -115
- package/src/components/TextEditor/yjs.stories.tsx +0 -56
- package/src/extensions/code.ts +0 -104
- package/src/extensions/yjs/cursor.ts +0 -22
- package/src/extensions/yjs/index.ts +0 -5
- package/src/extensions/yjs/yjs.test.ts +0 -35
- package/src/extensions/yjs/yjs.ts +0 -16
- package/src/hooks/automerge.ts +0 -53
- package/src/hooks/yjs.ts +0 -157
- package/src/testing/index.ts +0 -6
- package/src/testing/proto/gen/schema.ts +0 -49
- package/src/testing/proto/index.ts +0 -5
- package/src/testing/proto/schema.proto +0 -15
- package/src/testing/replicator.ts +0 -184
- /package/dist/types/src/extensions/{code.d.ts → markdown/code.d.ts} +0 -0
- /package/dist/types/src/extensions/{hr.d.ts → markdown/hr.d.ts} +0 -0
- /package/dist/types/src/extensions/{image.d.ts → markdown/image.d.ts} +0 -0
- /package/dist/types/src/extensions/{link.d.ts → markdown/link.d.ts} +0 -0
- /package/dist/types/src/extensions/{table.d.ts → markdown/table.d.ts} +0 -0
- /package/dist/types/src/extensions/{tasklist.d.ts → markdown/tasklist.d.ts} +0 -0
- /package/src/extensions/{image.ts → markdown/image.ts} +0 -0
- /package/src/extensions/{table.ts → markdown/table.ts} +0 -0
|
@@ -11,10 +11,10 @@ import { EditorView as EditorView13 } from "@codemirror/view";
|
|
|
11
11
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
12
12
|
import { vim } from "@replit/codemirror-vim";
|
|
13
13
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
|
-
import React, { forwardRef, useCallback, useEffect as
|
|
14
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
|
|
15
15
|
import { log as log2 } from "@dxos/log";
|
|
16
|
-
import { useThemeContext
|
|
17
|
-
import {
|
|
16
|
+
import { useThemeContext } from "@dxos/react-ui";
|
|
17
|
+
import { attentionSurface, mx as mx3 } from "@dxos/react-ui-theme";
|
|
18
18
|
|
|
19
19
|
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
|
20
20
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
@@ -293,9 +293,9 @@ var Cursor = class _Cursor {
|
|
|
293
293
|
}
|
|
294
294
|
static {
|
|
295
295
|
this.getCursorFromRange = (state, range) => {
|
|
296
|
-
const
|
|
297
|
-
const from =
|
|
298
|
-
const to =
|
|
296
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
297
|
+
const from = cursorConverter2.toCursor(range.from);
|
|
298
|
+
const to = cursorConverter2.toCursor(range.to, -1);
|
|
299
299
|
return [
|
|
300
300
|
from,
|
|
301
301
|
to
|
|
@@ -304,10 +304,10 @@ var Cursor = class _Cursor {
|
|
|
304
304
|
}
|
|
305
305
|
static {
|
|
306
306
|
this.getRangeFromCursor = (state, cursor) => {
|
|
307
|
-
const
|
|
307
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
308
308
|
const parts = cursor.split(":");
|
|
309
|
-
const from =
|
|
310
|
-
const to =
|
|
309
|
+
const from = cursorConverter2.fromCursor(parts[0]);
|
|
310
|
+
const to = cursorConverter2.fromCursor(parts[1]);
|
|
311
311
|
return from !== void 0 && to !== void 0 ? {
|
|
312
312
|
from,
|
|
313
313
|
to
|
|
@@ -386,21 +386,17 @@ var automerge3 = ({ handle, path }) => {
|
|
|
386
386
|
// packages/ui/react-ui-editor/src/extensions/awareness.ts
|
|
387
387
|
import { Annotation as Annotation2, Facet as Facet2, RangeSet } from "@codemirror/state";
|
|
388
388
|
import { Decoration, EditorView as EditorView2, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
|
389
|
-
import { useEffect } from "react";
|
|
390
389
|
import { Event } from "@dxos/async";
|
|
391
390
|
import { Context } from "@dxos/context";
|
|
392
|
-
import { generateName } from "@dxos/display-name";
|
|
393
|
-
import { useThemeContext } from "@dxos/react-ui";
|
|
394
|
-
import { getColorForValue } from "@dxos/react-ui-theme";
|
|
395
391
|
var dummyProvider = {
|
|
396
392
|
remoteStateChange: new Event(),
|
|
397
393
|
open: () => {
|
|
398
394
|
},
|
|
399
395
|
close: () => {
|
|
400
396
|
},
|
|
397
|
+
getRemoteStates: () => [],
|
|
401
398
|
update: () => {
|
|
402
|
-
}
|
|
403
|
-
getRemoteStates: () => []
|
|
399
|
+
}
|
|
404
400
|
};
|
|
405
401
|
var AwarenessProvider = Facet2.define({
|
|
406
402
|
combine: (providers) => providers[0] ?? dummyProvider
|
|
@@ -415,29 +411,6 @@ var awareness = (provider = dummyProvider) => {
|
|
|
415
411
|
styles
|
|
416
412
|
];
|
|
417
413
|
};
|
|
418
|
-
var useAwareness = ({ awareness: awareness2, peer }) => {
|
|
419
|
-
const { themeMode } = useThemeContext();
|
|
420
|
-
useEffect(() => {
|
|
421
|
-
if (awareness2 && peer) {
|
|
422
|
-
awareness2.setLocalStateField("user", {
|
|
423
|
-
name: peer.name ?? generateName(peer.id),
|
|
424
|
-
color: getColorForValue({
|
|
425
|
-
value: peer.id,
|
|
426
|
-
type: "color"
|
|
427
|
-
}),
|
|
428
|
-
colorLight: getColorForValue({
|
|
429
|
-
value: peer.id,
|
|
430
|
-
themeMode,
|
|
431
|
-
type: "highlight"
|
|
432
|
-
})
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
}, [
|
|
436
|
-
awareness2,
|
|
437
|
-
peer,
|
|
438
|
-
themeMode
|
|
439
|
-
]);
|
|
440
|
-
};
|
|
441
414
|
var RemoteSelectionsDecorator = class {
|
|
442
415
|
constructor(view) {
|
|
443
416
|
this.decorations = RangeSet.of([]);
|
|
@@ -599,39 +572,41 @@ var styles = EditorView2.baseTheme({
|
|
|
599
572
|
marginLeft: "-1px",
|
|
600
573
|
marginRight: "-1px",
|
|
601
574
|
boxSizing: "border-box",
|
|
602
|
-
display: "inline"
|
|
575
|
+
display: "inline",
|
|
576
|
+
cursor: "pointer"
|
|
603
577
|
},
|
|
604
578
|
".cm-collab-selectionCaretDot": {
|
|
605
579
|
borderRadius: "50%",
|
|
606
580
|
position: "absolute",
|
|
607
|
-
width: ".
|
|
608
|
-
height: ".
|
|
609
|
-
top: "-.
|
|
610
|
-
left: "-.
|
|
581
|
+
width: ".5em",
|
|
582
|
+
height: ".5em",
|
|
583
|
+
top: "-.25em",
|
|
584
|
+
left: "-.25em",
|
|
611
585
|
backgroundColor: "inherit",
|
|
612
586
|
transition: "transform .3s ease-in-out",
|
|
613
587
|
boxSizing: "border-box"
|
|
614
588
|
},
|
|
615
589
|
".cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot": {
|
|
616
|
-
|
|
617
|
-
|
|
590
|
+
transform: "scale(0)",
|
|
591
|
+
transformOrigin: "center"
|
|
618
592
|
},
|
|
619
593
|
".cm-collab-selectionInfo": {
|
|
620
594
|
position: "absolute",
|
|
621
|
-
|
|
622
|
-
|
|
595
|
+
transform: "translate(-50%, 0)",
|
|
596
|
+
top: "-20px",
|
|
597
|
+
left: 0,
|
|
623
598
|
fontSize: ".75em",
|
|
624
|
-
fontFamily: "serif",
|
|
599
|
+
fontFamily: "sans-serif",
|
|
625
600
|
fontStyle: "normal",
|
|
626
601
|
fontWeight: "normal",
|
|
627
602
|
lineHeight: "normal",
|
|
628
603
|
userSelect: "none",
|
|
629
604
|
color: "white",
|
|
630
|
-
|
|
631
|
-
paddingRight: "2px",
|
|
605
|
+
padding: "2px",
|
|
632
606
|
zIndex: 101,
|
|
633
607
|
transition: "opacity .3s ease-in-out",
|
|
634
608
|
backgroundColor: "inherit",
|
|
609
|
+
borderRadius: "2px",
|
|
635
610
|
// These should be separate.
|
|
636
611
|
opacity: 0,
|
|
637
612
|
transitionDelay: "0s",
|
|
@@ -649,8 +624,8 @@ import { history } from "@codemirror/commands";
|
|
|
649
624
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
650
625
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
651
626
|
import { drawSelection, EditorView as EditorView3, highlightActiveLine, placeholder } from "@codemirror/view";
|
|
652
|
-
var basicBundle = ({ themeMode, placeholder: _placeholder,
|
|
653
|
-
|
|
627
|
+
var basicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true }) => [
|
|
628
|
+
lineWrapping ? EditorView3.lineWrapping : [],
|
|
654
629
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
655
630
|
bracketMatching(),
|
|
656
631
|
closeBrackets(),
|
|
@@ -699,10 +674,10 @@ var blast = (options = defaultOptions) => {
|
|
|
699
674
|
const getPoint = (view, pos) => {
|
|
700
675
|
const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
|
|
701
676
|
const element = document.elementFromPoint(x, y);
|
|
702
|
-
const { offsetLeft: left = 0, offsetTop:
|
|
677
|
+
const { offsetLeft: left = 0, offsetTop: top2 = 0 } = view.scrollDOM.parentElement ?? {};
|
|
703
678
|
const point = {
|
|
704
679
|
x: x - left,
|
|
705
|
-
y: y -
|
|
680
|
+
y: y - top2
|
|
706
681
|
};
|
|
707
682
|
return {
|
|
708
683
|
element,
|
|
@@ -972,9 +947,14 @@ var random = (min, max) => {
|
|
|
972
947
|
return min + ~~(Math.random() * (max - min + 1));
|
|
973
948
|
};
|
|
974
949
|
|
|
975
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
976
|
-
import {
|
|
977
|
-
import {
|
|
950
|
+
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
951
|
+
import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
952
|
+
import { hoverTooltip, keymap as keymap3, Decoration as Decoration2, EditorView as EditorView5 } from "@codemirror/view";
|
|
953
|
+
import sortBy from "lodash.sortby";
|
|
954
|
+
import { useEffect } from "react";
|
|
955
|
+
import { debounce } from "@dxos/async";
|
|
956
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
957
|
+
import { nonNullable } from "@dxos/util";
|
|
978
958
|
|
|
979
959
|
// packages/ui/react-ui-editor/src/styles/cursors.ts
|
|
980
960
|
import * as random2 from "lib0/random";
|
|
@@ -1017,34 +997,15 @@ var cursorColor = cursorColors[random2.uint32() % cursorColors.length];
|
|
|
1017
997
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
1018
998
|
import { mx } from "@dxos/react-ui-theme";
|
|
1019
999
|
var headings = {
|
|
1020
|
-
1:
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
1030
|
-
"-ml-[7px]"
|
|
1031
|
-
],
|
|
1032
|
-
4: [
|
|
1033
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
1034
|
-
"-ml-[6px]"
|
|
1035
|
-
],
|
|
1036
|
-
5: [
|
|
1037
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
1038
|
-
"-ml-[5px]"
|
|
1039
|
-
],
|
|
1040
|
-
6: [
|
|
1041
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline",
|
|
1042
|
-
"-ml-[4px]"
|
|
1043
|
-
]
|
|
1044
|
-
};
|
|
1045
|
-
var heading = (level, readonly) => {
|
|
1046
|
-
const [style, offset] = headings[level];
|
|
1047
|
-
return mx(style, readonly && offset);
|
|
1000
|
+
1: "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
1001
|
+
2: "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
1002
|
+
3: "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
1003
|
+
4: "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
1004
|
+
5: "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
1005
|
+
6: "mbs-4 mbe-2 font-medium text-inherit no-underline"
|
|
1006
|
+
};
|
|
1007
|
+
var heading = (level) => {
|
|
1008
|
+
return headings[level];
|
|
1048
1009
|
};
|
|
1049
1010
|
var light = "text-neutral-200 dark:text-neutral-800";
|
|
1050
1011
|
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
@@ -1062,89 +1023,6 @@ import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
|
1062
1023
|
var tokens = tailwindConfig({}).theme;
|
|
1063
1024
|
var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
|
|
1064
1025
|
|
|
1065
|
-
// packages/ui/react-ui-editor/src/extensions/code.ts
|
|
1066
|
-
var CODE_REGEX = /```[\s\S]*?```/gs;
|
|
1067
|
-
var styles2 = EditorView5.baseTheme({
|
|
1068
|
-
"& .cm-codeblock": {
|
|
1069
|
-
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1070
|
-
},
|
|
1071
|
-
'&light [aria-readonly="true"] .cm-codeblock': {
|
|
1072
|
-
background: getToken("extend.colors.neutral.50")
|
|
1073
|
-
},
|
|
1074
|
-
'&dark [aria-readonly="true"] .cm-codeblock': {
|
|
1075
|
-
background: getToken("extend.colors.neutral.850")
|
|
1076
|
-
},
|
|
1077
|
-
'& [aria-readonly="true"] .cm-codeblock': {
|
|
1078
|
-
display: "block",
|
|
1079
|
-
paddingInline: "4px !important"
|
|
1080
|
-
},
|
|
1081
|
-
'& [aria-readonly="true"] .cm-codeblock-first': {
|
|
1082
|
-
paddingTop: "4px !important",
|
|
1083
|
-
borderTopLeftRadius: "4px",
|
|
1084
|
-
borderTopRightRadius: "4px"
|
|
1085
|
-
},
|
|
1086
|
-
'& [aria-readonly="true"] .cm-codeblock-last': {
|
|
1087
|
-
paddingBottom: "4px !important",
|
|
1088
|
-
borderBottomLeftRadius: "4px",
|
|
1089
|
-
borderBottomRightRadius: "4px"
|
|
1090
|
-
}
|
|
1091
|
-
});
|
|
1092
|
-
var getLineRange = (lines, from, to) => {
|
|
1093
|
-
const start = lines.findIndex((line) => line.from >= from);
|
|
1094
|
-
const end = lines.findIndex((line) => line.to >= to);
|
|
1095
|
-
return [
|
|
1096
|
-
start,
|
|
1097
|
-
end
|
|
1098
|
-
];
|
|
1099
|
-
};
|
|
1100
|
-
var code2 = () => {
|
|
1101
|
-
const buildDecorations5 = (view) => {
|
|
1102
|
-
const decorations = [];
|
|
1103
|
-
const text = view.state.doc.sliceString(0);
|
|
1104
|
-
const matches = text.matchAll(CODE_REGEX);
|
|
1105
|
-
const blocks = view.viewportLineBlocks;
|
|
1106
|
-
for (const match of matches) {
|
|
1107
|
-
const range = getLineRange(blocks, match.index, match.index + match[0].length);
|
|
1108
|
-
for (let i = range[0]; i <= range[1]; i++) {
|
|
1109
|
-
const block = blocks[i];
|
|
1110
|
-
decorations.push(Decoration2.line({
|
|
1111
|
-
class: mx2("cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
|
|
1112
|
-
}).range(block.from));
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
return Decoration2.set(decorations);
|
|
1116
|
-
};
|
|
1117
|
-
return [
|
|
1118
|
-
ViewPlugin3.fromClass(class {
|
|
1119
|
-
constructor(view) {
|
|
1120
|
-
this.hasFocus = false;
|
|
1121
|
-
this.decorations = buildDecorations5(view);
|
|
1122
|
-
}
|
|
1123
|
-
update(update2) {
|
|
1124
|
-
if (
|
|
1125
|
-
// TODO(burdon): Generalize for other extensions.
|
|
1126
|
-
this.hasFocus !== update2.view.hasFocus || update2.startState.readOnly !== update2.view.state.readOnly || update2.docChanged || update2.viewportChanged
|
|
1127
|
-
) {
|
|
1128
|
-
this.hasFocus = update2.view.hasFocus;
|
|
1129
|
-
this.decorations = buildDecorations5(update2.view);
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
}, {
|
|
1133
|
-
decorations: (value) => value.decorations
|
|
1134
|
-
}),
|
|
1135
|
-
styles2
|
|
1136
|
-
];
|
|
1137
|
-
};
|
|
1138
|
-
|
|
1139
|
-
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1140
|
-
import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1141
|
-
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
|
|
1142
|
-
import sortBy from "lodash.sortby";
|
|
1143
|
-
import { useEffect as useEffect2 } from "react";
|
|
1144
|
-
import { debounce } from "@dxos/async";
|
|
1145
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1146
|
-
import { nonNullable } from "@dxos/util";
|
|
1147
|
-
|
|
1148
1026
|
// packages/ui/react-ui-editor/src/util.ts
|
|
1149
1027
|
import { log } from "@dxos/log";
|
|
1150
1028
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
@@ -1182,20 +1060,20 @@ var logChanges = (trs) => {
|
|
|
1182
1060
|
|
|
1183
1061
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1184
1062
|
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1185
|
-
var
|
|
1063
|
+
var styles2 = EditorView5.baseTheme({
|
|
1186
1064
|
"& .cm-comment": {
|
|
1187
1065
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
1188
1066
|
},
|
|
1189
|
-
"& .cm-comment-
|
|
1067
|
+
"& .cm-comment-current": {
|
|
1190
1068
|
backgroundColor: getToken("extend.colors.yellow.100")
|
|
1191
1069
|
}
|
|
1192
1070
|
});
|
|
1193
1071
|
var marks = {
|
|
1194
|
-
highlight:
|
|
1072
|
+
highlight: Decoration2.mark({
|
|
1195
1073
|
class: "cm-comment"
|
|
1196
1074
|
}),
|
|
1197
|
-
highlightActive:
|
|
1198
|
-
class: "cm-comment-
|
|
1075
|
+
highlightActive: Decoration2.mark({
|
|
1076
|
+
class: "cm-comment-current"
|
|
1199
1077
|
})
|
|
1200
1078
|
};
|
|
1201
1079
|
var setFocus = (view, id, center = true) => {
|
|
@@ -1211,11 +1089,11 @@ var setFocus = (view, id, center = true) => {
|
|
|
1211
1089
|
},
|
|
1212
1090
|
effects: [
|
|
1213
1091
|
//
|
|
1214
|
-
|
|
1092
|
+
EditorView5.scrollIntoView(range.from, center ? {
|
|
1215
1093
|
y: "center"
|
|
1216
1094
|
} : void 0),
|
|
1217
1095
|
setSelection.of({
|
|
1218
|
-
|
|
1096
|
+
current: id
|
|
1219
1097
|
})
|
|
1220
1098
|
]
|
|
1221
1099
|
});
|
|
@@ -1260,23 +1138,23 @@ var commentsState = StateField2.define({
|
|
|
1260
1138
|
return value;
|
|
1261
1139
|
}
|
|
1262
1140
|
});
|
|
1263
|
-
var highlightDecorations =
|
|
1141
|
+
var highlightDecorations = EditorView5.decorations.compute([
|
|
1264
1142
|
commentsState
|
|
1265
1143
|
], (state) => {
|
|
1266
|
-
const { selection: {
|
|
1144
|
+
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
|
1267
1145
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1268
1146
|
const range = comment.range;
|
|
1269
1147
|
if (!range || range.from === range.to) {
|
|
1270
1148
|
console.warn("Invalid range:", range);
|
|
1271
1149
|
return void 0;
|
|
1272
1150
|
}
|
|
1273
|
-
if (comment.comment.id ===
|
|
1151
|
+
if (comment.comment.id === current) {
|
|
1274
1152
|
return marks.highlightActive.range(range.from, range.to);
|
|
1275
1153
|
} else {
|
|
1276
1154
|
return marks.highlight.range(range.from, range.to);
|
|
1277
1155
|
}
|
|
1278
1156
|
}).filter(nonNullable);
|
|
1279
|
-
return
|
|
1157
|
+
return Decoration2.set(decorations);
|
|
1280
1158
|
});
|
|
1281
1159
|
var trackPastedComments = (onUpdate) => {
|
|
1282
1160
|
let tracked = null;
|
|
@@ -1298,12 +1176,12 @@ var trackPastedComments = (onUpdate) => {
|
|
|
1298
1176
|
}
|
|
1299
1177
|
};
|
|
1300
1178
|
return [
|
|
1301
|
-
|
|
1179
|
+
EditorView5.domEventHandlers({
|
|
1302
1180
|
cut: handleTrack,
|
|
1303
1181
|
copy: handleTrack
|
|
1304
1182
|
}),
|
|
1305
1183
|
// Handle paste.
|
|
1306
|
-
|
|
1184
|
+
EditorView5.updateListener.of(({ view, state, transactions }) => {
|
|
1307
1185
|
if (tracked) {
|
|
1308
1186
|
const paste = transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1309
1187
|
if (paste) {
|
|
@@ -1366,7 +1244,7 @@ var comments = (options = {}) => {
|
|
|
1366
1244
|
if (id) {
|
|
1367
1245
|
view.dispatch({
|
|
1368
1246
|
effects: setSelection.of({
|
|
1369
|
-
|
|
1247
|
+
current: id
|
|
1370
1248
|
}),
|
|
1371
1249
|
selection: {
|
|
1372
1250
|
anchor: from
|
|
@@ -1380,7 +1258,7 @@ var comments = (options = {}) => {
|
|
|
1380
1258
|
return [
|
|
1381
1259
|
commentsState,
|
|
1382
1260
|
highlightDecorations,
|
|
1383
|
-
|
|
1261
|
+
styles2,
|
|
1384
1262
|
//
|
|
1385
1263
|
// Keymap.
|
|
1386
1264
|
//
|
|
@@ -1423,7 +1301,7 @@ var comments = (options = {}) => {
|
|
|
1423
1301
|
//
|
|
1424
1302
|
// Track deleted ranges and update ranges for decorations.
|
|
1425
1303
|
//
|
|
1426
|
-
|
|
1304
|
+
EditorView5.updateListener.of(({ view, state, changes }) => {
|
|
1427
1305
|
let mod = false;
|
|
1428
1306
|
const { comments: comments2, ...value } = state.field(commentsState);
|
|
1429
1307
|
changes.iterChanges((from, to, from2, to2) => {
|
|
@@ -1453,17 +1331,17 @@ var comments = (options = {}) => {
|
|
|
1453
1331
|
//
|
|
1454
1332
|
// Track selection/proximity.
|
|
1455
1333
|
//
|
|
1456
|
-
|
|
1334
|
+
EditorView5.updateListener.of(({ view, state }) => {
|
|
1457
1335
|
let min = Infinity;
|
|
1458
|
-
const { selection: {
|
|
1336
|
+
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
|
1459
1337
|
const { head } = state.selection.main;
|
|
1460
1338
|
const selection = {};
|
|
1461
1339
|
comments2.forEach(({ comment, range }) => {
|
|
1462
1340
|
if (head >= range.from && head <= range.to) {
|
|
1463
|
-
selection.
|
|
1341
|
+
selection.current = comment.id;
|
|
1464
1342
|
selection.closest = void 0;
|
|
1465
1343
|
}
|
|
1466
|
-
if (!selection.
|
|
1344
|
+
if (!selection.current) {
|
|
1467
1345
|
const d = Math.min(Math.abs(head - range.from), Math.abs(head - range.to));
|
|
1468
1346
|
if (d < min) {
|
|
1469
1347
|
selection.closest = comment.id;
|
|
@@ -1471,7 +1349,7 @@ var comments = (options = {}) => {
|
|
|
1471
1349
|
}
|
|
1472
1350
|
}
|
|
1473
1351
|
});
|
|
1474
|
-
if (selection.
|
|
1352
|
+
if (selection.current !== current || selection.closest !== closest) {
|
|
1475
1353
|
view.dispatch({
|
|
1476
1354
|
effects: setSelection.of(selection)
|
|
1477
1355
|
});
|
|
@@ -1488,9 +1366,9 @@ var comments = (options = {}) => {
|
|
|
1488
1366
|
options.onUpdate ? trackPastedComments(options.onUpdate) : []
|
|
1489
1367
|
];
|
|
1490
1368
|
};
|
|
1491
|
-
var useComments = (view, comments2) => {
|
|
1492
|
-
|
|
1493
|
-
if (view
|
|
1369
|
+
var useComments = (view, comments2 = []) => {
|
|
1370
|
+
useEffect(() => {
|
|
1371
|
+
if (view) {
|
|
1494
1372
|
view.dispatch({
|
|
1495
1373
|
effects: setComments.of(comments2)
|
|
1496
1374
|
});
|
|
@@ -1501,329 +1379,65 @@ var useComments = (view, comments2) => {
|
|
|
1501
1379
|
]);
|
|
1502
1380
|
};
|
|
1503
1381
|
|
|
1504
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
1505
|
-
import {
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
const el = document.createElement("div");
|
|
1517
|
-
el.className = "cm-hr";
|
|
1518
|
-
return el;
|
|
1519
|
-
}
|
|
1520
|
-
};
|
|
1521
|
-
var decoration = Decoration4.replace({
|
|
1522
|
-
widget: new HorizontalRuleWidget()
|
|
1523
|
-
});
|
|
1524
|
-
var buildDecorations = (view) => {
|
|
1525
|
-
const builder = new RangeSetBuilder();
|
|
1526
|
-
const { state } = view;
|
|
1527
|
-
const cursor = state.selection.main.head;
|
|
1528
|
-
for (const { from, to } of view.visibleRanges) {
|
|
1529
|
-
syntaxTree(state).iterate({
|
|
1530
|
-
enter: (node) => {
|
|
1531
|
-
if (node.name === "HorizontalRule") {
|
|
1532
|
-
if (cursor <= node.from || cursor >= node.to) {
|
|
1533
|
-
builder.add(node.from, node.to, decoration);
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
},
|
|
1537
|
-
from,
|
|
1538
|
-
to
|
|
1539
|
-
});
|
|
1540
|
-
}
|
|
1541
|
-
return builder.finish();
|
|
1542
|
-
};
|
|
1543
|
-
var hr = () => {
|
|
1544
|
-
return [
|
|
1545
|
-
styles4,
|
|
1546
|
-
ViewPlugin4.fromClass(class {
|
|
1547
|
-
constructor(view) {
|
|
1548
|
-
this.decorations = buildDecorations(view);
|
|
1549
|
-
}
|
|
1550
|
-
update(update2) {
|
|
1551
|
-
this.decorations = buildDecorations(update2.view);
|
|
1552
|
-
}
|
|
1553
|
-
}, {
|
|
1554
|
-
decorations: (v) => v.decorations
|
|
1555
|
-
})
|
|
1556
|
-
];
|
|
1382
|
+
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1383
|
+
import { EditorView as EditorView6 } from "@codemirror/view";
|
|
1384
|
+
var listener = ({ onFocus, onChange }) => {
|
|
1385
|
+
const extensions = [];
|
|
1386
|
+
onFocus && extensions.push(EditorView6.focusChangeEffect.of((_, focused) => {
|
|
1387
|
+
onFocus(focused);
|
|
1388
|
+
return null;
|
|
1389
|
+
}));
|
|
1390
|
+
onChange && extensions.push(EditorView6.updateListener.of((update2) => {
|
|
1391
|
+
onChange(update2.state.doc.toString());
|
|
1392
|
+
}));
|
|
1393
|
+
return extensions;
|
|
1557
1394
|
};
|
|
1558
1395
|
|
|
1559
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
1560
|
-
import {
|
|
1561
|
-
import {
|
|
1562
|
-
import {
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
provide: (field) => EditorView8.decorations.from(field)
|
|
1590
|
-
});
|
|
1591
|
-
};
|
|
1592
|
-
var buildDecorations2 = (from, to, state) => {
|
|
1593
|
-
const decorations = [];
|
|
1594
|
-
const cursor = state.selection.main.head;
|
|
1595
|
-
syntaxTree2(state).iterate({
|
|
1596
|
-
enter: (node) => {
|
|
1597
|
-
if (node.name === "Image") {
|
|
1598
|
-
const urlNode = node.node.getChild("URL");
|
|
1599
|
-
if (urlNode) {
|
|
1600
|
-
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
1601
|
-
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
1602
|
-
decorations.push(Decoration5.replace({
|
|
1603
|
-
block: true,
|
|
1604
|
-
widget: new ImageWidget(url)
|
|
1605
|
-
}).range(hide ? node.from : node.to, node.to));
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
},
|
|
1609
|
-
from,
|
|
1610
|
-
to
|
|
1611
|
-
});
|
|
1612
|
-
return decorations;
|
|
1396
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1397
|
+
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1398
|
+
import { history as history2, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1399
|
+
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1400
|
+
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
1401
|
+
import { languages } from "@codemirror/language-data";
|
|
1402
|
+
import { searchKeymap } from "@codemirror/search";
|
|
1403
|
+
import { EditorState } from "@codemirror/state";
|
|
1404
|
+
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1405
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView7, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1406
|
+
|
|
1407
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1408
|
+
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
1409
|
+
import { HighlightStyle } from "@codemirror/language";
|
|
1410
|
+
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
1411
|
+
import { Table } from "@lezer/markdown";
|
|
1412
|
+
var markdownTags = {
|
|
1413
|
+
Blockquote: Tag.define(),
|
|
1414
|
+
CodeMark: Tag.define(),
|
|
1415
|
+
CodeText: Tag.define(),
|
|
1416
|
+
EmphasisMark: Tag.define(),
|
|
1417
|
+
HeaderMark: Tag.define(),
|
|
1418
|
+
InlineCode: Tag.define(),
|
|
1419
|
+
LinkLabel: Tag.define(),
|
|
1420
|
+
LinkReference: Tag.define(),
|
|
1421
|
+
ListMark: Tag.define(),
|
|
1422
|
+
QuoteMark: Tag.define(),
|
|
1423
|
+
URL: Tag.define(),
|
|
1424
|
+
// Custom.
|
|
1425
|
+
TableCell: Tag.define()
|
|
1613
1426
|
};
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
return this._url === other._url;
|
|
1427
|
+
Table.defineNodes?.forEach((node) => {
|
|
1428
|
+
switch (node?.name) {
|
|
1429
|
+
case "TableCell": {
|
|
1430
|
+
node.style = markdownTags.TableCell;
|
|
1431
|
+
break;
|
|
1432
|
+
}
|
|
1621
1433
|
}
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
};
|
|
1630
|
-
|
|
1631
|
-
// packages/ui/react-ui-editor/src/extensions/link.ts
|
|
1632
|
-
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1633
|
-
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1634
|
-
import { hoverTooltip as hoverTooltip2, Decoration as Decoration6, ViewPlugin as ViewPlugin5, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1635
|
-
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1636
|
-
var link = (options = {}) => {
|
|
1637
|
-
const extensions = [
|
|
1638
|
-
ViewPlugin5.fromClass(class {
|
|
1639
|
-
constructor(view) {
|
|
1640
|
-
this.decorations = buildDecorations3(view, options);
|
|
1641
|
-
}
|
|
1642
|
-
update(update2) {
|
|
1643
|
-
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
1644
|
-
this.decorations = buildDecorations3(update2.view, options);
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
}, {
|
|
1648
|
-
decorations: (v) => v.decorations
|
|
1649
|
-
})
|
|
1650
|
-
];
|
|
1651
|
-
if (options.onHover) {
|
|
1652
|
-
extensions.push(
|
|
1653
|
-
// https://codemirror.net/examples/tooltip
|
|
1654
|
-
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
1655
|
-
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
1656
|
-
hoverTooltip2((view, pos, side) => {
|
|
1657
|
-
const syntax = syntaxTree3(view.state).resolveInner(pos, side);
|
|
1658
|
-
let link2 = null;
|
|
1659
|
-
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
1660
|
-
link2 = node.name === "Link" ? node : null;
|
|
1661
|
-
}
|
|
1662
|
-
const url = link2 && link2.getChild("URL");
|
|
1663
|
-
if (!url || !link2) {
|
|
1664
|
-
return null;
|
|
1665
|
-
}
|
|
1666
|
-
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
1667
|
-
return {
|
|
1668
|
-
pos: link2.from,
|
|
1669
|
-
end: link2.to,
|
|
1670
|
-
above: true,
|
|
1671
|
-
create: () => {
|
|
1672
|
-
const el = document.createElement("div");
|
|
1673
|
-
el.className = tooltipContent({}, "pli-2 plb-1");
|
|
1674
|
-
options.onHover(el, urlText);
|
|
1675
|
-
return {
|
|
1676
|
-
dom: el,
|
|
1677
|
-
offset: {
|
|
1678
|
-
x: 0,
|
|
1679
|
-
y: 4
|
|
1680
|
-
}
|
|
1681
|
-
};
|
|
1682
|
-
}
|
|
1683
|
-
};
|
|
1684
|
-
})
|
|
1685
|
-
);
|
|
1686
|
-
}
|
|
1687
|
-
return extensions;
|
|
1688
|
-
};
|
|
1689
|
-
var LinkButton = class extends WidgetType4 {
|
|
1690
|
-
constructor(_url, _onAttach) {
|
|
1691
|
-
super();
|
|
1692
|
-
this._url = _url;
|
|
1693
|
-
this._onAttach = _onAttach;
|
|
1694
|
-
}
|
|
1695
|
-
eq(other) {
|
|
1696
|
-
return this._url === other._url;
|
|
1697
|
-
}
|
|
1698
|
-
toDOM(view) {
|
|
1699
|
-
const el = document.createElement("span");
|
|
1700
|
-
this._onAttach(el, this._url);
|
|
1701
|
-
return el;
|
|
1702
|
-
}
|
|
1703
|
-
};
|
|
1704
|
-
var LinkText = class extends WidgetType4 {
|
|
1705
|
-
constructor(_text, _url) {
|
|
1706
|
-
super();
|
|
1707
|
-
this._text = _text;
|
|
1708
|
-
this._url = _url;
|
|
1709
|
-
}
|
|
1710
|
-
eq(other) {
|
|
1711
|
-
return this._url === other._url;
|
|
1712
|
-
}
|
|
1713
|
-
toDOM(view) {
|
|
1714
|
-
const link2 = document.createElement("a");
|
|
1715
|
-
link2.setAttribute("class", "cm-link");
|
|
1716
|
-
link2.textContent = this._text;
|
|
1717
|
-
if (this._url) {
|
|
1718
|
-
link2.setAttribute("rel", "noreferrer");
|
|
1719
|
-
link2.setAttribute("target", "_blank");
|
|
1720
|
-
link2.href = this._url;
|
|
1721
|
-
} else {
|
|
1722
|
-
link2.onclick = () => {
|
|
1723
|
-
view.dispatch({
|
|
1724
|
-
selection: {
|
|
1725
|
-
anchor: view.posAtDOM(link2)
|
|
1726
|
-
}
|
|
1727
|
-
});
|
|
1728
|
-
};
|
|
1729
|
-
}
|
|
1730
|
-
return link2;
|
|
1731
|
-
}
|
|
1732
|
-
};
|
|
1733
|
-
var buildDecorations3 = (view, options) => {
|
|
1734
|
-
const builder = new RangeSetBuilder2();
|
|
1735
|
-
const { state } = view;
|
|
1736
|
-
const cursor = state.selection.main.head;
|
|
1737
|
-
for (const { from, to } of view.visibleRanges) {
|
|
1738
|
-
syntaxTree3(state).iterate({
|
|
1739
|
-
enter: (node) => {
|
|
1740
|
-
if (node.name === "Link") {
|
|
1741
|
-
const marks2 = node.node.getChildren("LinkMark");
|
|
1742
|
-
const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
|
|
1743
|
-
const urlNode = node.node.getChild("URL");
|
|
1744
|
-
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
1745
|
-
if (!url) {
|
|
1746
|
-
return false;
|
|
1747
|
-
}
|
|
1748
|
-
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1749
|
-
builder.add(node.from, node.to, Decoration6.replace({
|
|
1750
|
-
widget: new LinkText(text, options.link ? url : void 0)
|
|
1751
|
-
}));
|
|
1752
|
-
}
|
|
1753
|
-
if (options.onRender) {
|
|
1754
|
-
builder.add(node.to, node.to, Decoration6.replace({
|
|
1755
|
-
widget: new LinkButton(url, options.onRender)
|
|
1756
|
-
}));
|
|
1757
|
-
}
|
|
1758
|
-
return false;
|
|
1759
|
-
}
|
|
1760
|
-
},
|
|
1761
|
-
from,
|
|
1762
|
-
to
|
|
1763
|
-
});
|
|
1764
|
-
}
|
|
1765
|
-
return builder.finish();
|
|
1766
|
-
};
|
|
1767
|
-
|
|
1768
|
-
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
1769
|
-
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
1770
|
-
var listener = ({ onFocus, onChange }) => {
|
|
1771
|
-
const extensions = [];
|
|
1772
|
-
onFocus && extensions.push(EditorView9.focusChangeEffect.of((_, focused) => {
|
|
1773
|
-
onFocus(focused);
|
|
1774
|
-
return null;
|
|
1775
|
-
}));
|
|
1776
|
-
onChange && extensions.push(EditorView9.updateListener.of((update2) => {
|
|
1777
|
-
onChange(update2.state.doc.toString());
|
|
1778
|
-
}));
|
|
1779
|
-
return extensions;
|
|
1780
|
-
};
|
|
1781
|
-
|
|
1782
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1783
|
-
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1784
|
-
import { history as history2, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1785
|
-
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1786
|
-
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
1787
|
-
import { languages } from "@codemirror/language-data";
|
|
1788
|
-
import { searchKeymap } from "@codemirror/search";
|
|
1789
|
-
import { EditorState } from "@codemirror/state";
|
|
1790
|
-
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
1791
|
-
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView10, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1792
|
-
|
|
1793
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1794
|
-
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
1795
|
-
import { HighlightStyle } from "@codemirror/language";
|
|
1796
|
-
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
1797
|
-
import { Table } from "@lezer/markdown";
|
|
1798
|
-
var markdownTags = {
|
|
1799
|
-
Blockquote: Tag.define(),
|
|
1800
|
-
CodeMark: Tag.define(),
|
|
1801
|
-
CodeText: Tag.define(),
|
|
1802
|
-
EmphasisMark: Tag.define(),
|
|
1803
|
-
HeaderMark: Tag.define(),
|
|
1804
|
-
InlineCode: Tag.define(),
|
|
1805
|
-
LinkLabel: Tag.define(),
|
|
1806
|
-
LinkReference: Tag.define(),
|
|
1807
|
-
ListMark: Tag.define(),
|
|
1808
|
-
QuoteMark: Tag.define(),
|
|
1809
|
-
URL: Tag.define(),
|
|
1810
|
-
// Custom.
|
|
1811
|
-
TableCell: Tag.define()
|
|
1812
|
-
};
|
|
1813
|
-
Table.defineNodes?.forEach((node) => {
|
|
1814
|
-
switch (node?.name) {
|
|
1815
|
-
case "TableCell": {
|
|
1816
|
-
node.style = markdownTags.TableCell;
|
|
1817
|
-
break;
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
});
|
|
1821
|
-
var markdownTagsExtensions = [
|
|
1822
|
-
Table,
|
|
1823
|
-
{
|
|
1824
|
-
props: [
|
|
1825
|
-
styleTags(markdownTags)
|
|
1826
|
-
]
|
|
1434
|
+
});
|
|
1435
|
+
var markdownTagsExtensions = [
|
|
1436
|
+
Table,
|
|
1437
|
+
{
|
|
1438
|
+
props: [
|
|
1439
|
+
styleTags(markdownTags)
|
|
1440
|
+
]
|
|
1827
1441
|
}
|
|
1828
1442
|
];
|
|
1829
1443
|
var markdownHighlightStyle = (readonly) => {
|
|
@@ -1885,7 +1499,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1885
1499
|
markdownTags.QuoteMark,
|
|
1886
1500
|
markdownTags.EmphasisMark
|
|
1887
1501
|
],
|
|
1888
|
-
class:
|
|
1502
|
+
class: mark
|
|
1889
1503
|
},
|
|
1890
1504
|
// E.g., code block language (after ```).
|
|
1891
1505
|
{
|
|
@@ -1893,7 +1507,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1893
1507
|
tags.function(tags.variableName),
|
|
1894
1508
|
tags.labelName
|
|
1895
1509
|
],
|
|
1896
|
-
class:
|
|
1510
|
+
class: codeMark
|
|
1897
1511
|
},
|
|
1898
1512
|
{
|
|
1899
1513
|
tag: [
|
|
@@ -1904,27 +1518,27 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1904
1518
|
// Headings.
|
|
1905
1519
|
{
|
|
1906
1520
|
tag: tags.heading1,
|
|
1907
|
-
class: heading(1
|
|
1521
|
+
class: heading(1)
|
|
1908
1522
|
},
|
|
1909
1523
|
{
|
|
1910
1524
|
tag: tags.heading2,
|
|
1911
|
-
class: heading(2
|
|
1525
|
+
class: heading(2)
|
|
1912
1526
|
},
|
|
1913
1527
|
{
|
|
1914
1528
|
tag: tags.heading3,
|
|
1915
|
-
class: heading(3
|
|
1529
|
+
class: heading(3)
|
|
1916
1530
|
},
|
|
1917
1531
|
{
|
|
1918
1532
|
tag: tags.heading4,
|
|
1919
|
-
class: heading(4
|
|
1533
|
+
class: heading(4)
|
|
1920
1534
|
},
|
|
1921
1535
|
{
|
|
1922
1536
|
tag: tags.heading5,
|
|
1923
|
-
class: heading(5
|
|
1537
|
+
class: heading(5)
|
|
1924
1538
|
},
|
|
1925
1539
|
{
|
|
1926
1540
|
tag: tags.heading6,
|
|
1927
|
-
class: heading(6
|
|
1541
|
+
class: heading(6)
|
|
1928
1542
|
},
|
|
1929
1543
|
// Emphasis.
|
|
1930
1544
|
{
|
|
@@ -1950,7 +1564,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1950
1564
|
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
1951
1565
|
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
1952
1566
|
// the code, but all other CSS properties will be inherited.
|
|
1953
|
-
// IMPORTANT: Therefore, the fenced code block will use the base editor font.
|
|
1567
|
+
// IMPORTANT: Therefore, the fenced code block will use the base editor font unless changed by an extension.
|
|
1954
1568
|
{
|
|
1955
1569
|
tag: [
|
|
1956
1570
|
markdownTags.CodeText,
|
|
@@ -1979,11 +1593,11 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1979
1593
|
};
|
|
1980
1594
|
|
|
1981
1595
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1982
|
-
var markdownBundle = ({
|
|
1596
|
+
var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
1983
1597
|
return [
|
|
1984
1598
|
EditorState.allowMultipleSelections.of(true),
|
|
1985
1599
|
EditorState.tabSize.of(2),
|
|
1986
|
-
|
|
1600
|
+
EditorView7.lineWrapping,
|
|
1987
1601
|
// https://github.com/codemirror/basic-setup
|
|
1988
1602
|
bracketMatching2(),
|
|
1989
1603
|
closeBrackets2(),
|
|
@@ -2015,7 +1629,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
2015
1629
|
// https://github.com/codemirror/theme-one-dark
|
|
2016
1630
|
themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2),
|
|
2017
1631
|
// Custom styles.
|
|
2018
|
-
syntaxHighlighting2(markdownHighlightStyle(
|
|
1632
|
+
syntaxHighlighting2(markdownHighlightStyle()),
|
|
2019
1633
|
keymap4.of([
|
|
2020
1634
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2021
1635
|
indentWithTab,
|
|
@@ -2031,44 +1645,420 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
2031
1645
|
];
|
|
2032
1646
|
};
|
|
2033
1647
|
|
|
2034
|
-
// packages/ui/react-ui-editor/src/extensions/
|
|
2035
|
-
import {
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
1648
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/code.ts
|
|
1649
|
+
import { syntaxTree } from "@codemirror/language";
|
|
1650
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
1651
|
+
import { ViewPlugin as ViewPlugin3, EditorView as EditorView8, Decoration as Decoration3, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1652
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1653
|
+
var styles3 = EditorView8.baseTheme({
|
|
1654
|
+
"& .cm-code": {
|
|
1655
|
+
paddingInline: "1rem !important",
|
|
1656
|
+
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1657
|
+
},
|
|
1658
|
+
"& .cm-codeblock": {
|
|
1659
|
+
display: "inline-block",
|
|
1660
|
+
width: "100%"
|
|
1661
|
+
},
|
|
1662
|
+
"&light .cm-codeblock, &light .cm-codeblock.cm-activeLine": {
|
|
1663
|
+
background: getToken("extend.colors.neutral.25")
|
|
1664
|
+
},
|
|
1665
|
+
"&dark .cm-codeblock, &dark .cm-codeblock.cm-activeLine": {
|
|
1666
|
+
background: getToken("extend.colors.neutral.850")
|
|
1667
|
+
},
|
|
1668
|
+
"& .cm-codeblock-first": {
|
|
1669
|
+
borderTopLeftRadius: ".5rem",
|
|
1670
|
+
borderTopRightRadius: ".5rem"
|
|
1671
|
+
},
|
|
1672
|
+
"& .cm-codeblock-last": {
|
|
1673
|
+
borderBottomLeftRadius: ".5rem",
|
|
1674
|
+
borderBottomRightRadius: ".5rem"
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
var getLineRange = (lines, from, to) => {
|
|
1678
|
+
const start = lines.findIndex((line) => line.from >= from);
|
|
1679
|
+
const end = lines.findIndex((line) => line.to >= to);
|
|
1680
|
+
return [
|
|
1681
|
+
start,
|
|
1682
|
+
end
|
|
1683
|
+
];
|
|
1684
|
+
};
|
|
1685
|
+
var LineWidget = class extends WidgetType2 {
|
|
1686
|
+
constructor(_className) {
|
|
1687
|
+
super();
|
|
1688
|
+
this._className = _className;
|
|
1689
|
+
}
|
|
1690
|
+
toDOM() {
|
|
1691
|
+
const el = document.createElement("span");
|
|
1692
|
+
el.innerHTML = " ";
|
|
1693
|
+
el.className = mx2("cm-code cm-codeblock", this._className);
|
|
1694
|
+
return el;
|
|
1695
|
+
}
|
|
1696
|
+
};
|
|
1697
|
+
var top = new LineWidget("cm-codeblock-first");
|
|
1698
|
+
var bottom = new LineWidget("cm-codeblock-last");
|
|
1699
|
+
var buildDecorations = (view) => {
|
|
1700
|
+
const builder = new RangeSetBuilder();
|
|
1701
|
+
const { state } = view;
|
|
1702
|
+
const blocks = view.viewportLineBlocks;
|
|
1703
|
+
const cursor = state.selection.main.head;
|
|
1704
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1705
|
+
syntaxTree(state).iterate({
|
|
1706
|
+
enter: (node) => {
|
|
1707
|
+
if (node.name === "FencedCode") {
|
|
1708
|
+
const edit = !view.state.readOnly && cursor >= node.from && cursor <= node.to;
|
|
1709
|
+
const range = getLineRange(blocks, node.from, node.to);
|
|
1710
|
+
for (let i = range[0]; i <= range[1]; i++) {
|
|
1711
|
+
const block = blocks[i];
|
|
1712
|
+
if (!edit && (i === range[0] || i === range[1])) {
|
|
1713
|
+
builder.add(block.from, block.to, Decoration3.replace({
|
|
1714
|
+
widget: i === range[0] ? top : bottom
|
|
1715
|
+
}));
|
|
1716
|
+
} else {
|
|
1717
|
+
builder.add(block.from, block.from, Decoration3.line({
|
|
1718
|
+
class: mx2("cm-code cm-codeblock")
|
|
1719
|
+
}));
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
},
|
|
1724
|
+
from,
|
|
1725
|
+
to
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
return builder.finish();
|
|
1729
|
+
};
|
|
1730
|
+
var code2 = () => {
|
|
1731
|
+
return [
|
|
1732
|
+
ViewPlugin3.fromClass(class {
|
|
1733
|
+
constructor(view) {
|
|
1734
|
+
this.decorations = buildDecorations(view);
|
|
1735
|
+
}
|
|
1736
|
+
update(update2) {
|
|
1737
|
+
this.decorations = buildDecorations(update2.view);
|
|
1738
|
+
}
|
|
1739
|
+
}, {
|
|
1740
|
+
decorations: (value) => value.decorations
|
|
1741
|
+
}),
|
|
1742
|
+
styles3
|
|
1743
|
+
];
|
|
1744
|
+
};
|
|
1745
|
+
|
|
1746
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
1747
|
+
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1748
|
+
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1749
|
+
import { Decoration as Decoration4, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1750
|
+
var buildDecorations2 = (view) => {
|
|
1751
|
+
const builder = new RangeSetBuilder2();
|
|
1752
|
+
const { state } = view;
|
|
1753
|
+
const cursor = state.selection.main.head;
|
|
1754
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1755
|
+
syntaxTree2(state).iterate({
|
|
1756
|
+
enter: (node) => {
|
|
1757
|
+
switch (node.name) {
|
|
1758
|
+
case "ATXHeading1":
|
|
1759
|
+
case "ATXHeading2":
|
|
1760
|
+
case "ATXHeading3":
|
|
1761
|
+
case "ATXHeading4":
|
|
1762
|
+
case "ATXHeading5":
|
|
1763
|
+
case "ATXHeading6": {
|
|
1764
|
+
const mark2 = node.node.getChild("HeaderMark");
|
|
1765
|
+
if (mark2) {
|
|
1766
|
+
if (view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
1767
|
+
builder.add(mark2.from, mark2.to + 1, Decoration4.replace({}));
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
},
|
|
1773
|
+
from,
|
|
1774
|
+
to
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
return builder.finish();
|
|
1778
|
+
};
|
|
1779
|
+
var heading2 = () => {
|
|
1780
|
+
return [
|
|
1781
|
+
ViewPlugin4.fromClass(class {
|
|
1782
|
+
constructor(view) {
|
|
1783
|
+
this.decorations = buildDecorations2(view);
|
|
1784
|
+
}
|
|
1785
|
+
update(update2) {
|
|
1786
|
+
this.decorations = buildDecorations2(update2.view);
|
|
1787
|
+
}
|
|
1788
|
+
}, {
|
|
1789
|
+
decorations: (value) => value.decorations
|
|
1790
|
+
})
|
|
1791
|
+
];
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1794
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
1795
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1796
|
+
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
1797
|
+
import { Decoration as Decoration5, EditorView as EditorView9, ViewPlugin as ViewPlugin5, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1798
|
+
var styles4 = EditorView9.baseTheme({
|
|
1799
|
+
"& .cm-hr": {
|
|
1800
|
+
// Note that block-level decorations should not have vertical margins,
|
|
1801
|
+
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
1802
|
+
}
|
|
1803
|
+
});
|
|
1804
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
1805
|
+
toDOM() {
|
|
1806
|
+
const el = document.createElement("div");
|
|
1807
|
+
el.className = "cm-hr";
|
|
1808
|
+
return el;
|
|
1809
|
+
}
|
|
1810
|
+
};
|
|
1811
|
+
var decoration = Decoration5.replace({
|
|
1812
|
+
widget: new HorizontalRuleWidget()
|
|
1813
|
+
});
|
|
1814
|
+
var buildDecorations3 = (view) => {
|
|
1815
|
+
const builder = new RangeSetBuilder3();
|
|
1816
|
+
const { state } = view;
|
|
1817
|
+
const cursor = state.selection.main.head;
|
|
1818
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1819
|
+
syntaxTree3(state).iterate({
|
|
1820
|
+
enter: (node) => {
|
|
1821
|
+
if (node.name === "HorizontalRule") {
|
|
1822
|
+
if (cursor <= node.from || cursor >= node.to) {
|
|
1823
|
+
builder.add(node.from, node.to, decoration);
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
},
|
|
1827
|
+
from,
|
|
1828
|
+
to
|
|
1829
|
+
});
|
|
1830
|
+
}
|
|
1831
|
+
return builder.finish();
|
|
1832
|
+
};
|
|
1833
|
+
var hr = () => {
|
|
1834
|
+
return [
|
|
1835
|
+
ViewPlugin5.fromClass(class {
|
|
1836
|
+
constructor(view) {
|
|
1837
|
+
this.decorations = buildDecorations3(view);
|
|
1838
|
+
}
|
|
1839
|
+
update(update2) {
|
|
1840
|
+
this.decorations = buildDecorations3(update2.view);
|
|
1841
|
+
}
|
|
1842
|
+
}, {
|
|
1843
|
+
decorations: (value) => value.decorations
|
|
1844
|
+
}),
|
|
1845
|
+
styles4
|
|
1846
|
+
];
|
|
1847
|
+
};
|
|
1848
|
+
|
|
1849
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
1850
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
1851
|
+
import { StateField as StateField3 } from "@codemirror/state";
|
|
1852
|
+
import { Decoration as Decoration6, EditorView as EditorView10, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1853
|
+
var image = (options = {}) => {
|
|
1854
|
+
return StateField3.define({
|
|
1855
|
+
create: (state) => {
|
|
1856
|
+
return Decoration6.set(buildDecorations4(0, state.doc.length, state));
|
|
1857
|
+
},
|
|
1858
|
+
update: (value, tr) => {
|
|
1859
|
+
if (!tr.docChanged && !tr.selection) {
|
|
1860
|
+
return value;
|
|
1861
|
+
}
|
|
1862
|
+
const cursor = tr.state.selection.main.head;
|
|
1863
|
+
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
1864
|
+
let from = Math.min(cursor, oldCursor);
|
|
1865
|
+
let to = Math.max(cursor, oldCursor);
|
|
1866
|
+
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
1867
|
+
from = Math.min(from, fromB);
|
|
1868
|
+
to = Math.max(to, toB);
|
|
1869
|
+
});
|
|
1870
|
+
from = tr.state.doc.lineAt(from).from;
|
|
1871
|
+
to = tr.state.doc.lineAt(to).to;
|
|
1872
|
+
return value.map(tr.changes).update({
|
|
1873
|
+
filterFrom: from,
|
|
1874
|
+
filterTo: to,
|
|
1875
|
+
filter: () => false,
|
|
1876
|
+
add: buildDecorations4(from, to, tr.state)
|
|
1877
|
+
});
|
|
1878
|
+
},
|
|
1879
|
+
provide: (field) => EditorView10.decorations.from(field)
|
|
1880
|
+
});
|
|
1881
|
+
};
|
|
1882
|
+
var buildDecorations4 = (from, to, state) => {
|
|
1883
|
+
const decorations = [];
|
|
1884
|
+
const cursor = state.selection.main.head;
|
|
1885
|
+
syntaxTree4(state).iterate({
|
|
1886
|
+
enter: (node) => {
|
|
1887
|
+
if (node.name === "Image") {
|
|
1888
|
+
const urlNode = node.node.getChild("URL");
|
|
1889
|
+
if (urlNode) {
|
|
1890
|
+
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
1891
|
+
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
1892
|
+
decorations.push(Decoration6.replace({
|
|
1893
|
+
block: true,
|
|
1894
|
+
widget: new ImageWidget(url)
|
|
1895
|
+
}).range(hide ? node.from : node.to, node.to));
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
},
|
|
1899
|
+
from,
|
|
1900
|
+
to
|
|
1901
|
+
});
|
|
1902
|
+
return decorations;
|
|
1903
|
+
};
|
|
1904
|
+
var ImageWidget = class extends WidgetType4 {
|
|
1905
|
+
constructor(_url) {
|
|
1906
|
+
super();
|
|
1907
|
+
this._url = _url;
|
|
1908
|
+
}
|
|
1909
|
+
eq(other) {
|
|
1910
|
+
return this._url === other._url;
|
|
1911
|
+
}
|
|
1912
|
+
toDOM(view) {
|
|
1913
|
+
const img = document.createElement("img");
|
|
1914
|
+
img.setAttribute("src", this._url);
|
|
1915
|
+
img.setAttribute("class", "cm-image");
|
|
1916
|
+
img.onload = () => img.classList.add("cm-loaded-image");
|
|
1917
|
+
return img;
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
|
|
1921
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
1922
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
1923
|
+
import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
|
|
1924
|
+
import { hoverTooltip as hoverTooltip2, Decoration as Decoration7, ViewPlugin as ViewPlugin6, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
1925
|
+
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1926
|
+
var link = (options = {}) => {
|
|
1927
|
+
const extensions = [
|
|
1928
|
+
ViewPlugin6.fromClass(class {
|
|
1929
|
+
constructor(view) {
|
|
1930
|
+
this.decorations = buildDecorations5(view, options);
|
|
1931
|
+
}
|
|
1932
|
+
update(update2) {
|
|
1933
|
+
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
1934
|
+
this.decorations = buildDecorations5(update2.view, options);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}, {
|
|
1938
|
+
decorations: (value) => value.decorations
|
|
1939
|
+
})
|
|
1940
|
+
];
|
|
1941
|
+
if (options.onHover) {
|
|
1942
|
+
extensions.push(
|
|
1943
|
+
// https://codemirror.net/examples/tooltip
|
|
1944
|
+
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
1945
|
+
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
1946
|
+
hoverTooltip2((view, pos, side) => {
|
|
1947
|
+
const syntax = syntaxTree5(view.state).resolveInner(pos, side);
|
|
1948
|
+
let link2 = null;
|
|
1949
|
+
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
1950
|
+
link2 = node.name === "Link" ? node : null;
|
|
1951
|
+
}
|
|
1952
|
+
const url = link2 && link2.getChild("URL");
|
|
1953
|
+
if (!url || !link2) {
|
|
2050
1954
|
return null;
|
|
2051
1955
|
}
|
|
1956
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
2052
1957
|
return {
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
1958
|
+
pos: link2.from,
|
|
1959
|
+
end: link2.to,
|
|
1960
|
+
above: true,
|
|
1961
|
+
create: () => {
|
|
1962
|
+
const el = document.createElement("div");
|
|
1963
|
+
el.className = tooltipContent({}, "pli-2 plb-1");
|
|
1964
|
+
options.onHover(el, urlText);
|
|
1965
|
+
return {
|
|
1966
|
+
dom: el,
|
|
1967
|
+
offset: {
|
|
1968
|
+
x: 0,
|
|
1969
|
+
y: 4
|
|
1970
|
+
}
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
2057
1973
|
};
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2060
|
-
}
|
|
1974
|
+
})
|
|
1975
|
+
);
|
|
1976
|
+
}
|
|
1977
|
+
return extensions;
|
|
2061
1978
|
};
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
1979
|
+
var LinkButton = class extends WidgetType5 {
|
|
1980
|
+
constructor(_url, _onAttach) {
|
|
1981
|
+
super();
|
|
1982
|
+
this._url = _url;
|
|
1983
|
+
this._onAttach = _onAttach;
|
|
1984
|
+
}
|
|
1985
|
+
eq(other) {
|
|
1986
|
+
return this._url === other._url;
|
|
1987
|
+
}
|
|
1988
|
+
toDOM(view) {
|
|
1989
|
+
const el = document.createElement("span");
|
|
1990
|
+
this._onAttach(el, this._url);
|
|
1991
|
+
return el;
|
|
1992
|
+
}
|
|
1993
|
+
};
|
|
1994
|
+
var LinkText = class extends WidgetType5 {
|
|
1995
|
+
constructor(_text, _url) {
|
|
1996
|
+
super();
|
|
1997
|
+
this._text = _text;
|
|
1998
|
+
this._url = _url;
|
|
1999
|
+
}
|
|
2000
|
+
eq(other) {
|
|
2001
|
+
return this._url === other._url;
|
|
2002
|
+
}
|
|
2003
|
+
toDOM(view) {
|
|
2004
|
+
const link2 = document.createElement("a");
|
|
2005
|
+
link2.setAttribute("class", "cm-link");
|
|
2006
|
+
link2.textContent = this._text;
|
|
2007
|
+
if (this._url) {
|
|
2008
|
+
link2.setAttribute("rel", "noreferrer");
|
|
2009
|
+
link2.setAttribute("target", "_blank");
|
|
2010
|
+
link2.href = this._url;
|
|
2011
|
+
} else {
|
|
2012
|
+
link2.onclick = () => {
|
|
2013
|
+
view.dispatch({
|
|
2014
|
+
selection: {
|
|
2015
|
+
anchor: view.posAtDOM(link2)
|
|
2016
|
+
}
|
|
2017
|
+
});
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
return link2;
|
|
2021
|
+
}
|
|
2022
|
+
};
|
|
2023
|
+
var buildDecorations5 = (view, options) => {
|
|
2024
|
+
const builder = new RangeSetBuilder4();
|
|
2025
|
+
const { state } = view;
|
|
2026
|
+
const cursor = state.selection.main.head;
|
|
2027
|
+
for (const { from, to } of view.visibleRanges) {
|
|
2028
|
+
syntaxTree5(state).iterate({
|
|
2029
|
+
enter: (node) => {
|
|
2030
|
+
if (node.name === "Link") {
|
|
2031
|
+
const marks2 = node.node.getChildren("LinkMark");
|
|
2032
|
+
const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
|
|
2033
|
+
const urlNode = node.node.getChild("URL");
|
|
2034
|
+
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
2035
|
+
if (!url) {
|
|
2036
|
+
return false;
|
|
2037
|
+
}
|
|
2038
|
+
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
2039
|
+
builder.add(node.from, node.to, Decoration7.replace({
|
|
2040
|
+
widget: new LinkText(text, options.link ? url : void 0)
|
|
2041
|
+
}));
|
|
2042
|
+
}
|
|
2043
|
+
if (options.onRender) {
|
|
2044
|
+
builder.add(node.to, node.to, Decoration7.replace({
|
|
2045
|
+
widget: new LinkButton(url, options.onRender)
|
|
2046
|
+
}));
|
|
2047
|
+
}
|
|
2048
|
+
return false;
|
|
2049
|
+
}
|
|
2050
|
+
},
|
|
2051
|
+
from,
|
|
2052
|
+
to
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
return builder.finish();
|
|
2066
2056
|
};
|
|
2067
2057
|
|
|
2068
|
-
// packages/ui/react-ui-editor/src/extensions/table.ts
|
|
2069
|
-
import { syntaxTree as
|
|
2070
|
-
import { RangeSetBuilder as
|
|
2071
|
-
import { Decoration as
|
|
2058
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
2059
|
+
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
2060
|
+
import { RangeSetBuilder as RangeSetBuilder5, StateField as StateField4 } from "@codemirror/state";
|
|
2061
|
+
import { Decoration as Decoration8, EditorView as EditorView11, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
2072
2062
|
var table = (options = {}) => {
|
|
2073
2063
|
return StateField4.define({
|
|
2074
2064
|
create: (state) => update(state, options),
|
|
@@ -2077,7 +2067,7 @@ var table = (options = {}) => {
|
|
|
2077
2067
|
});
|
|
2078
2068
|
};
|
|
2079
2069
|
var update = (state, options) => {
|
|
2080
|
-
const builder = new
|
|
2070
|
+
const builder = new RangeSetBuilder5();
|
|
2081
2071
|
const cursor = state.selection.main.head;
|
|
2082
2072
|
const tables = [];
|
|
2083
2073
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -2085,7 +2075,7 @@ var update = (state, options) => {
|
|
|
2085
2075
|
const table2 = getTable();
|
|
2086
2076
|
return table2.rows?.[table2.rows.length - 1];
|
|
2087
2077
|
};
|
|
2088
|
-
|
|
2078
|
+
syntaxTree6(state).iterate({
|
|
2089
2079
|
enter: (node) => {
|
|
2090
2080
|
switch (node.name) {
|
|
2091
2081
|
case "Table": {
|
|
@@ -2117,16 +2107,16 @@ var update = (state, options) => {
|
|
|
2117
2107
|
});
|
|
2118
2108
|
tables.forEach((table2) => {
|
|
2119
2109
|
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
2120
|
-
hide && builder.add(table2.from, table2.to,
|
|
2110
|
+
hide && builder.add(table2.from, table2.to, Decoration8.replace({
|
|
2121
2111
|
widget: new TableWidget(table2)
|
|
2122
2112
|
}));
|
|
2123
|
-
builder.add(table2.from, table2.to,
|
|
2113
|
+
builder.add(table2.from, table2.to, Decoration8.mark({
|
|
2124
2114
|
class: "cm-table"
|
|
2125
2115
|
}));
|
|
2126
2116
|
});
|
|
2127
2117
|
return builder.finish();
|
|
2128
2118
|
};
|
|
2129
|
-
var TableWidget = class extends
|
|
2119
|
+
var TableWidget = class extends WidgetType6 {
|
|
2130
2120
|
constructor(_table) {
|
|
2131
2121
|
super();
|
|
2132
2122
|
this._table = _table;
|
|
@@ -2163,10 +2153,10 @@ var TableWidget = class extends WidgetType5 {
|
|
|
2163
2153
|
}
|
|
2164
2154
|
};
|
|
2165
2155
|
|
|
2166
|
-
// packages/ui/react-ui-editor/src/extensions/tasklist.ts
|
|
2167
|
-
import { syntaxTree as
|
|
2168
|
-
import { RangeSetBuilder as
|
|
2169
|
-
import { EditorView as EditorView12, Decoration as
|
|
2156
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
|
|
2157
|
+
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
2158
|
+
import { RangeSetBuilder as RangeSetBuilder6 } from "@codemirror/state";
|
|
2159
|
+
import { EditorView as EditorView12, Decoration as Decoration9, WidgetType as WidgetType7, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
|
2170
2160
|
var styles5 = EditorView12.baseTheme({
|
|
2171
2161
|
"& .cm-task": {
|
|
2172
2162
|
color: getToken("extend.colors.blue.500")
|
|
@@ -2176,7 +2166,7 @@ var styles5 = EditorView12.baseTheme({
|
|
|
2176
2166
|
marginRight: "4px"
|
|
2177
2167
|
}
|
|
2178
2168
|
});
|
|
2179
|
-
var CheckboxWidget = class extends
|
|
2169
|
+
var CheckboxWidget = class extends WidgetType7 {
|
|
2180
2170
|
constructor(_checked) {
|
|
2181
2171
|
super();
|
|
2182
2172
|
this._checked = _checked;
|
|
@@ -2213,23 +2203,23 @@ var CheckboxWidget = class extends WidgetType6 {
|
|
|
2213
2203
|
return false;
|
|
2214
2204
|
}
|
|
2215
2205
|
};
|
|
2216
|
-
var checkedDecoration =
|
|
2206
|
+
var checkedDecoration = Decoration9.replace({
|
|
2217
2207
|
widget: new CheckboxWidget(true)
|
|
2218
2208
|
});
|
|
2219
|
-
var uncheckedDecoration =
|
|
2209
|
+
var uncheckedDecoration = Decoration9.replace({
|
|
2220
2210
|
widget: new CheckboxWidget(false)
|
|
2221
2211
|
});
|
|
2222
|
-
var
|
|
2223
|
-
const builder = new
|
|
2212
|
+
var buildDecorations6 = (view) => {
|
|
2213
|
+
const builder = new RangeSetBuilder6();
|
|
2224
2214
|
const { state } = view;
|
|
2225
2215
|
const cursor = state.selection.main.head;
|
|
2226
2216
|
for (const { from, to } of view.visibleRanges) {
|
|
2227
|
-
|
|
2217
|
+
syntaxTree7(state).iterate({
|
|
2228
2218
|
enter: (node) => {
|
|
2229
2219
|
if (node.name === "TaskMarker") {
|
|
2230
2220
|
if (cursor < node.from || cursor > node.to) {
|
|
2231
2221
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2232
|
-
builder.add(node.from - 2, node.from - 1,
|
|
2222
|
+
builder.add(node.from - 2, node.from - 1, Decoration9.mark({
|
|
2233
2223
|
class: "cm-task"
|
|
2234
2224
|
}));
|
|
2235
2225
|
builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
|
|
@@ -2244,22 +2234,56 @@ var buildDecorations4 = (view) => {
|
|
|
2244
2234
|
};
|
|
2245
2235
|
var tasklist = (options = {}) => {
|
|
2246
2236
|
return [
|
|
2247
|
-
|
|
2237
|
+
ViewPlugin7.fromClass(class {
|
|
2248
2238
|
constructor(view) {
|
|
2249
|
-
this.decorations =
|
|
2239
|
+
this.decorations = buildDecorations6(view);
|
|
2250
2240
|
}
|
|
2251
2241
|
update(update2) {
|
|
2252
2242
|
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
2253
|
-
this.decorations =
|
|
2243
|
+
this.decorations = buildDecorations6(update2.view);
|
|
2254
2244
|
}
|
|
2255
2245
|
}
|
|
2256
2246
|
}, {
|
|
2257
|
-
decorations: (
|
|
2247
|
+
decorations: (value) => value.decorations
|
|
2258
2248
|
}),
|
|
2259
2249
|
styles5
|
|
2260
2250
|
];
|
|
2261
2251
|
};
|
|
2262
2252
|
|
|
2253
|
+
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
2254
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
2255
|
+
var mention = ({ onSearch }) => {
|
|
2256
|
+
return autocompletion2({
|
|
2257
|
+
// TODO(burdon): Not working.
|
|
2258
|
+
activateOnTyping: true,
|
|
2259
|
+
// activateOnTypingDelay: 100,
|
|
2260
|
+
// selectOnOpen: true,
|
|
2261
|
+
closeOnBlur: false,
|
|
2262
|
+
// defaultKeymap: false,
|
|
2263
|
+
icons: false,
|
|
2264
|
+
override: [
|
|
2265
|
+
(context) => {
|
|
2266
|
+
console.log(context);
|
|
2267
|
+
const match = context.matchBefore(/@(\w+)?/);
|
|
2268
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
2269
|
+
return null;
|
|
2270
|
+
}
|
|
2271
|
+
return {
|
|
2272
|
+
from: match.from,
|
|
2273
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
|
2274
|
+
label: `@${value}`
|
|
2275
|
+
}))
|
|
2276
|
+
};
|
|
2277
|
+
}
|
|
2278
|
+
]
|
|
2279
|
+
});
|
|
2280
|
+
};
|
|
2281
|
+
|
|
2282
|
+
// packages/ui/react-ui-editor/src/extensions/outliner.ts
|
|
2283
|
+
var outliner = (options = {}) => {
|
|
2284
|
+
return [];
|
|
2285
|
+
};
|
|
2286
|
+
|
|
2263
2287
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
2264
2288
|
import { keymap as keymap5 } from "@codemirror/view";
|
|
2265
2289
|
var defaultItems = [
|
|
@@ -2317,27 +2341,6 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
2317
2341
|
];
|
|
2318
2342
|
};
|
|
2319
2343
|
|
|
2320
|
-
// packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
|
|
2321
|
-
import { yCollab } from "y-codemirror.next";
|
|
2322
|
-
|
|
2323
|
-
// packages/ui/react-ui-editor/src/extensions/yjs/cursor.ts
|
|
2324
|
-
import * as Y from "yjs";
|
|
2325
|
-
import { arrayToString, stringToArray } from "@dxos/util";
|
|
2326
|
-
var cursorConverter2 = (text) => ({
|
|
2327
|
-
toCursor: (index, assoc) => {
|
|
2328
|
-
return arrayToString(Y.encodeRelativePosition(Y.createRelativePositionFromTypeIndex(text, index, assoc)));
|
|
2329
|
-
},
|
|
2330
|
-
fromCursor: (cursor) => {
|
|
2331
|
-
return Y.createAbsolutePositionFromRelativePosition(Y.decodeRelativePosition(stringToArray(cursor)), text.doc)?.index ?? 0;
|
|
2332
|
-
}
|
|
2333
|
-
});
|
|
2334
|
-
|
|
2335
|
-
// packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
|
|
2336
|
-
var yjs = (content, awareness2) => [
|
|
2337
|
-
Cursor.converter.of(cursorConverter2(content)),
|
|
2338
|
-
yCollab(content, awareness2)
|
|
2339
|
-
];
|
|
2340
|
-
|
|
2341
2344
|
// packages/ui/react-ui-editor/src/themes/default.ts
|
|
2342
2345
|
import get3 from "lodash.get";
|
|
2343
2346
|
var defaultTheme = {
|
|
@@ -2580,26 +2583,25 @@ var EditorModes = [
|
|
|
2580
2583
|
"default",
|
|
2581
2584
|
"vim"
|
|
2582
2585
|
];
|
|
2583
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly,
|
|
2586
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
2584
2587
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
2585
2588
|
tabBehavior: "limited"
|
|
2586
2589
|
});
|
|
2587
|
-
const { themeMode } =
|
|
2590
|
+
const { themeMode } = useThemeContext();
|
|
2588
2591
|
const rootRef = useRef(null);
|
|
2589
2592
|
const [view, setView] = useState(null);
|
|
2590
2593
|
useImperativeHandle(forwardedRef, () => view, [
|
|
2591
2594
|
view
|
|
2592
2595
|
]);
|
|
2593
|
-
|
|
2594
|
-
if (
|
|
2596
|
+
useEffect2(() => {
|
|
2597
|
+
if (autoFocus) {
|
|
2595
2598
|
view?.focus();
|
|
2596
2599
|
}
|
|
2597
2600
|
}, [
|
|
2598
2601
|
view,
|
|
2599
|
-
|
|
2602
|
+
autoFocus
|
|
2600
2603
|
]);
|
|
2601
|
-
|
|
2602
|
-
useEffect3(() => {
|
|
2604
|
+
useEffect2(() => {
|
|
2603
2605
|
if (!model || !rootRef.current) {
|
|
2604
2606
|
return;
|
|
2605
2607
|
}
|
|
@@ -2611,7 +2613,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
|
|
|
2611
2613
|
EditorView13.exceptionSink.of((err) => {
|
|
2612
2614
|
log2.catch(err, void 0, {
|
|
2613
2615
|
F: __dxlog_file5,
|
|
2614
|
-
L:
|
|
2616
|
+
L: 123,
|
|
2615
2617
|
S: void 0,
|
|
2616
2618
|
C: (f, a) => f(...a)
|
|
2617
2619
|
});
|
|
@@ -2692,8 +2694,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autofocus, s
|
|
|
2692
2694
|
ref: rootRef
|
|
2693
2695
|
});
|
|
2694
2696
|
});
|
|
2695
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3,
|
|
2696
|
-
const { themeMode } =
|
|
2697
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions = [], ...props }, forwardedRef) => {
|
|
2698
|
+
const { themeMode } = useThemeContext();
|
|
2697
2699
|
const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
|
|
2698
2700
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2699
2701
|
ref: forwardedRef,
|
|
@@ -2702,7 +2704,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2702
2704
|
basicBundle({
|
|
2703
2705
|
themeMode,
|
|
2704
2706
|
placeholder: placeholder3,
|
|
2705
|
-
|
|
2707
|
+
lineWrapping
|
|
2706
2708
|
}),
|
|
2707
2709
|
...extensions
|
|
2708
2710
|
],
|
|
@@ -2712,7 +2714,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholde
|
|
|
2712
2714
|
});
|
|
2713
2715
|
});
|
|
2714
2716
|
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions = [], ...props }, forwardedRef) => {
|
|
2715
|
-
const { themeMode } =
|
|
2717
|
+
const { themeMode } = useThemeContext();
|
|
2716
2718
|
const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
|
|
2717
2719
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2718
2720
|
ref: forwardedRef,
|
|
@@ -2720,7 +2722,6 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2720
2722
|
extensions: [
|
|
2721
2723
|
markdownBundle({
|
|
2722
2724
|
themeMode,
|
|
2723
|
-
readonly,
|
|
2724
2725
|
placeholder: placeholder3
|
|
2725
2726
|
}),
|
|
2726
2727
|
...extensions
|
|
@@ -2733,7 +2734,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2733
2734
|
var defaultSlots = {
|
|
2734
2735
|
root: {
|
|
2735
2736
|
// TODO(burdon): Add focusRing by default/as property?
|
|
2736
|
-
className: mx3("flex flex-col grow overflow-y-auto",
|
|
2737
|
+
className: mx3("flex flex-col grow overflow-y-auto", attentionSurface)
|
|
2737
2738
|
},
|
|
2738
2739
|
editor: {
|
|
2739
2740
|
className: "h-full p-2"
|
|
@@ -2746,11 +2747,6 @@ var defaultMarkdownSlots = {
|
|
|
2746
2747
|
...defaultSlots
|
|
2747
2748
|
};
|
|
2748
2749
|
|
|
2749
|
-
// packages/ui/react-ui-editor/src/hooks/automerge.ts
|
|
2750
|
-
import get4 from "lodash.get";
|
|
2751
|
-
import { getRawDoc } from "@dxos/echo-schema";
|
|
2752
|
-
import { isNotNullOrUndefined } from "@dxos/util";
|
|
2753
|
-
|
|
2754
2750
|
// packages/ui/react-ui-editor/src/hooks/awareness-provider.ts
|
|
2755
2751
|
import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
|
|
2756
2752
|
import { Context as Context2 } from "@dxos/context";
|
|
@@ -2760,8 +2756,8 @@ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src
|
|
|
2760
2756
|
var DEBOUNCE_INTERVAL = 100;
|
|
2761
2757
|
var SpaceAwarenessProvider = class {
|
|
2762
2758
|
constructor(params) {
|
|
2763
|
-
this.remoteStateChange = new Event2();
|
|
2764
2759
|
this._remoteStates = /* @__PURE__ */ new Map();
|
|
2760
|
+
this.remoteStateChange = new Event2();
|
|
2765
2761
|
this._space = params.space;
|
|
2766
2762
|
this._channel = params.channel;
|
|
2767
2763
|
this._peerId = params.peerId;
|
|
@@ -2778,7 +2774,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2778
2774
|
await sleep(DEBOUNCE_INTERVAL);
|
|
2779
2775
|
}
|
|
2780
2776
|
});
|
|
2781
|
-
|
|
2777
|
+
this._ctx.onDispose(this._space.listen(this._channel, (message) => {
|
|
2782
2778
|
switch (message.payload.kind) {
|
|
2783
2779
|
case "query": {
|
|
2784
2780
|
this._handleQueryMessage();
|
|
@@ -2789,8 +2785,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2789
2785
|
break;
|
|
2790
2786
|
}
|
|
2791
2787
|
}
|
|
2792
|
-
});
|
|
2793
|
-
this._ctx.onDispose(unsubscribe);
|
|
2788
|
+
}));
|
|
2794
2789
|
void this._space.postMessage(this._channel, {
|
|
2795
2790
|
kind: "query"
|
|
2796
2791
|
}).catch((err) => {
|
|
@@ -2798,7 +2793,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2798
2793
|
err
|
|
2799
2794
|
}, {
|
|
2800
2795
|
F: __dxlog_file6,
|
|
2801
|
-
L:
|
|
2796
|
+
L: 89,
|
|
2802
2797
|
S: this,
|
|
2803
2798
|
C: (f, a) => f(...a)
|
|
2804
2799
|
});
|
|
@@ -2809,10 +2804,13 @@ var SpaceAwarenessProvider = class {
|
|
|
2809
2804
|
this._ctx = void 0;
|
|
2810
2805
|
this._postTask = void 0;
|
|
2811
2806
|
}
|
|
2807
|
+
getRemoteStates() {
|
|
2808
|
+
return Array.from(this._remoteStates.values());
|
|
2809
|
+
}
|
|
2812
2810
|
update(position) {
|
|
2813
2811
|
invariant4(this._postTask, void 0, {
|
|
2814
2812
|
F: __dxlog_file6,
|
|
2815
|
-
L:
|
|
2813
|
+
L: 104,
|
|
2816
2814
|
S: this,
|
|
2817
2815
|
A: [
|
|
2818
2816
|
"this._postTask",
|
|
@@ -2826,13 +2824,10 @@ var SpaceAwarenessProvider = class {
|
|
|
2826
2824
|
};
|
|
2827
2825
|
this._postTask.schedule();
|
|
2828
2826
|
}
|
|
2829
|
-
getRemoteStates() {
|
|
2830
|
-
return Array.from(this._remoteStates.values());
|
|
2831
|
-
}
|
|
2832
2827
|
_handleQueryMessage() {
|
|
2833
2828
|
invariant4(this._postTask, void 0, {
|
|
2834
2829
|
F: __dxlog_file6,
|
|
2835
|
-
L:
|
|
2830
|
+
L: 115,
|
|
2836
2831
|
S: this,
|
|
2837
2832
|
A: [
|
|
2838
2833
|
"this._postTask",
|
|
@@ -2844,7 +2839,7 @@ var SpaceAwarenessProvider = class {
|
|
|
2844
2839
|
_handlePostMessage(message) {
|
|
2845
2840
|
invariant4(message.kind === "post", void 0, {
|
|
2846
2841
|
F: __dxlog_file6,
|
|
2847
|
-
L:
|
|
2842
|
+
L: 120,
|
|
2848
2843
|
S: this,
|
|
2849
2844
|
A: [
|
|
2850
2845
|
"message.kind === 'post'",
|
|
@@ -2863,8 +2858,47 @@ var modelState = StateField5.define({
|
|
|
2863
2858
|
update: (model) => model
|
|
2864
2859
|
});
|
|
2865
2860
|
|
|
2866
|
-
// packages/ui/react-ui-editor/src/hooks/
|
|
2867
|
-
|
|
2861
|
+
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
2862
|
+
import { useState as useState2 } from "react";
|
|
2863
|
+
var useTextEditor = () => {
|
|
2864
|
+
const [view, setView] = useState2(null);
|
|
2865
|
+
return [
|
|
2866
|
+
(ref) => {
|
|
2867
|
+
setView(ref);
|
|
2868
|
+
},
|
|
2869
|
+
view
|
|
2870
|
+
];
|
|
2871
|
+
};
|
|
2872
|
+
|
|
2873
|
+
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
2874
|
+
import get4 from "lodash.get";
|
|
2875
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
2876
|
+
import { generateName } from "@dxos/display-name";
|
|
2877
|
+
import { getRawDoc } from "@dxos/echo-schema";
|
|
2878
|
+
import { invariant as invariant5 } from "@dxos/invariant";
|
|
2879
|
+
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
2880
|
+
import { isNotNullOrUndefined } from "@dxos/util";
|
|
2881
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
2882
|
+
var useTextModel = (props) => {
|
|
2883
|
+
const { identity, space, text } = props;
|
|
2884
|
+
const [model, setModel] = useState3();
|
|
2885
|
+
useEffect3(() => setModel(createModel(props)), [
|
|
2886
|
+
identity,
|
|
2887
|
+
space,
|
|
2888
|
+
text
|
|
2889
|
+
]);
|
|
2890
|
+
return model;
|
|
2891
|
+
};
|
|
2892
|
+
var createModel = ({ space, identity, text }) => {
|
|
2893
|
+
invariant5(isAutomergeObject(text), void 0, {
|
|
2894
|
+
F: __dxlog_file7,
|
|
2895
|
+
L: 35,
|
|
2896
|
+
S: void 0,
|
|
2897
|
+
A: [
|
|
2898
|
+
"isAutomergeObject(text)",
|
|
2899
|
+
""
|
|
2900
|
+
]
|
|
2901
|
+
});
|
|
2868
2902
|
const obj = text;
|
|
2869
2903
|
const doc = getRawDoc(obj, [
|
|
2870
2904
|
obj.field
|
|
@@ -2873,7 +2907,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
|
|
|
2873
2907
|
space,
|
|
2874
2908
|
channel: `automerge.awareness.${obj.id}`,
|
|
2875
2909
|
info: {
|
|
2876
|
-
displayName: identity
|
|
2910
|
+
displayName: identity ? identity.profile?.displayName ?? generateName(identity.identityKey.toHex()) : void 0,
|
|
2877
2911
|
color: cursorColor.color,
|
|
2878
2912
|
lightColor: cursorColor.light
|
|
2879
2913
|
},
|
|
@@ -2883,7 +2917,6 @@ var createAutomergeModel = ({ space, identity, text }) => {
|
|
|
2883
2917
|
id: obj.id,
|
|
2884
2918
|
content: doc,
|
|
2885
2919
|
text: () => get4(doc.handle.docSync(), doc.path),
|
|
2886
|
-
// TODO(burdon): https://automerge.org/automerge/api-docs/js/functions/next.getCursor.html
|
|
2887
2920
|
extension: [
|
|
2888
2921
|
modelState.init(() => model),
|
|
2889
2922
|
automerge3({
|
|
@@ -2900,162 +2933,6 @@ var createAutomergeModel = ({ space, identity, text }) => {
|
|
|
2900
2933
|
};
|
|
2901
2934
|
return model;
|
|
2902
2935
|
};
|
|
2903
|
-
|
|
2904
|
-
// packages/ui/react-ui-editor/src/hooks/yjs.ts
|
|
2905
|
-
import * as decoding from "lib0/decoding";
|
|
2906
|
-
import * as encoding from "lib0/encoding";
|
|
2907
|
-
import { Observable } from "lib0/observable";
|
|
2908
|
-
import * as YP from "y-protocols/awareness";
|
|
2909
|
-
import { invariant as invariant5 } from "@dxos/invariant";
|
|
2910
|
-
import { log as log4 } from "@dxos/log";
|
|
2911
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs.ts";
|
|
2912
|
-
var createYjsModel = ({ identity, space, text }) => {
|
|
2913
|
-
invariant5(text?.doc && text?.content, void 0, {
|
|
2914
|
-
F: __dxlog_file7,
|
|
2915
|
-
L: 22,
|
|
2916
|
-
S: void 0,
|
|
2917
|
-
A: [
|
|
2918
|
-
"text?.doc && text?.content",
|
|
2919
|
-
""
|
|
2920
|
-
]
|
|
2921
|
-
});
|
|
2922
|
-
const provider = space ? new YAwarenessProvider({
|
|
2923
|
-
space,
|
|
2924
|
-
doc: text.doc,
|
|
2925
|
-
channel: `yjs.awareness.${text.id}`
|
|
2926
|
-
}) : void 0;
|
|
2927
|
-
const model = {
|
|
2928
|
-
id: text.doc.guid,
|
|
2929
|
-
content: text.content,
|
|
2930
|
-
text: () => text.content.toString(),
|
|
2931
|
-
extension: [
|
|
2932
|
-
modelState.init(() => model),
|
|
2933
|
-
yjs(text.content, provider?.awareness)
|
|
2934
|
-
],
|
|
2935
|
-
awareness: provider?.awareness,
|
|
2936
|
-
peer: identity ? {
|
|
2937
|
-
id: identity.identityKey.toHex(),
|
|
2938
|
-
name: identity.profile?.displayName
|
|
2939
|
-
} : void 0
|
|
2940
|
-
};
|
|
2941
|
-
return model;
|
|
2942
|
-
};
|
|
2943
|
-
var messageAwareness = 1;
|
|
2944
|
-
var messageQueryAwareness = 3;
|
|
2945
|
-
var YAwarenessProvider = class extends Observable {
|
|
2946
|
-
constructor({ space, doc, channel, awareness: awareness2 }) {
|
|
2947
|
-
super();
|
|
2948
|
-
this._space = space;
|
|
2949
|
-
this._awareness = awareness2 ?? new YP.Awareness(doc);
|
|
2950
|
-
this._channel = channel;
|
|
2951
|
-
this._clientId = doc.clientID;
|
|
2952
|
-
this._awareness.on("update", this._handleAwarenessUpdate.bind(this));
|
|
2953
|
-
this._space.listen(this._channel, this._handleSpaceMessage.bind(this));
|
|
2954
|
-
if (typeof window !== "undefined") {
|
|
2955
|
-
window.addEventListener("beforeunload", this._handleBeforeUnload.bind(this));
|
|
2956
|
-
} else if (typeof process !== "undefined") {
|
|
2957
|
-
process.on("exit", this._handleBeforeUnload.bind(this));
|
|
2958
|
-
}
|
|
2959
|
-
const encoderAwarenessQuery = encoding.createEncoder();
|
|
2960
|
-
encoding.writeVarUint(encoderAwarenessQuery, messageQueryAwareness);
|
|
2961
|
-
void this._space.postMessage(this._channel, encoding.toUint8Array(encoderAwarenessQuery));
|
|
2962
|
-
const encoderAwarenessState = encoding.createEncoder();
|
|
2963
|
-
encoding.writeVarUint(encoderAwarenessState, messageAwareness);
|
|
2964
|
-
encoding.writeVarUint8Array(encoderAwarenessState, YP.encodeAwarenessUpdate(this.awareness, [
|
|
2965
|
-
this._clientId
|
|
2966
|
-
]));
|
|
2967
|
-
void this._space.postMessage(this._channel, encoding.toUint8Array(encoderAwarenessState));
|
|
2968
|
-
}
|
|
2969
|
-
get awareness() {
|
|
2970
|
-
return this._awareness;
|
|
2971
|
-
}
|
|
2972
|
-
_handleAwarenessUpdate({ added, updated, removed }, origin) {
|
|
2973
|
-
log4("awareness update", {
|
|
2974
|
-
added,
|
|
2975
|
-
updated,
|
|
2976
|
-
removed,
|
|
2977
|
-
origin
|
|
2978
|
-
}, {
|
|
2979
|
-
F: __dxlog_file7,
|
|
2980
|
-
L: 101,
|
|
2981
|
-
S: this,
|
|
2982
|
-
C: (f, a) => f(...a)
|
|
2983
|
-
});
|
|
2984
|
-
const changedClients = added.concat(updated).concat(removed);
|
|
2985
|
-
const encoderAwareness = encoding.createEncoder();
|
|
2986
|
-
encoding.writeVarUint(encoderAwareness, messageAwareness);
|
|
2987
|
-
encoding.writeVarUint8Array(encoderAwareness, YP.encodeAwarenessUpdate(this._awareness, changedClients));
|
|
2988
|
-
void this._space.postMessage(this._channel, encoding.toUint8Array(encoderAwareness));
|
|
2989
|
-
}
|
|
2990
|
-
_handleSpaceMessage({ payload }) {
|
|
2991
|
-
log4("space message", payload, {
|
|
2992
|
-
F: __dxlog_file7,
|
|
2993
|
-
L: 110,
|
|
2994
|
-
S: this,
|
|
2995
|
-
C: (f, a) => f(...a)
|
|
2996
|
-
});
|
|
2997
|
-
const data = new Uint8Array(Array.from(Object.values(payload)));
|
|
2998
|
-
const encoder = this._readMessage(data);
|
|
2999
|
-
if (encoder) {
|
|
3000
|
-
void this._space.postMessage(this._channel, encoding.toUint8Array(encoder));
|
|
3001
|
-
}
|
|
3002
|
-
}
|
|
3003
|
-
_readMessage(message) {
|
|
3004
|
-
const decoder = decoding.createDecoder(message);
|
|
3005
|
-
const encoder = encoding.createEncoder();
|
|
3006
|
-
const messageType = decoding.readVarUint(decoder);
|
|
3007
|
-
let sendReply = false;
|
|
3008
|
-
switch (messageType) {
|
|
3009
|
-
case messageAwareness: {
|
|
3010
|
-
YP.applyAwarenessUpdate(this._awareness, decoding.readVarUint8Array(decoder), this);
|
|
3011
|
-
break;
|
|
3012
|
-
}
|
|
3013
|
-
case messageQueryAwareness: {
|
|
3014
|
-
encoding.writeVarUint(encoder, messageAwareness);
|
|
3015
|
-
encoding.writeVarUint8Array(encoder, YP.encodeAwarenessUpdate(this._awareness, Array.from(this._awareness.getStates().keys())));
|
|
3016
|
-
sendReply = true;
|
|
3017
|
-
break;
|
|
3018
|
-
}
|
|
3019
|
-
default: {
|
|
3020
|
-
console.error("Invalid message:", messageType);
|
|
3021
|
-
return encoder;
|
|
3022
|
-
}
|
|
3023
|
-
}
|
|
3024
|
-
if (!sendReply) {
|
|
3025
|
-
return null;
|
|
3026
|
-
}
|
|
3027
|
-
return encoder;
|
|
3028
|
-
}
|
|
3029
|
-
_handleBeforeUnload() {
|
|
3030
|
-
YP.removeAwarenessStates(this._awareness, [
|
|
3031
|
-
this._clientId
|
|
3032
|
-
], "window unload");
|
|
3033
|
-
}
|
|
3034
|
-
};
|
|
3035
|
-
|
|
3036
|
-
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
3037
|
-
import { useEffect as useEffect4, useState as useState2 } from "react";
|
|
3038
|
-
import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
3039
|
-
var useTextModel = (props) => {
|
|
3040
|
-
const { identity, space, text } = props;
|
|
3041
|
-
const [model, setModel] = useState2();
|
|
3042
|
-
useEffect4(() => setModel(createModel(props)), [
|
|
3043
|
-
identity,
|
|
3044
|
-
space,
|
|
3045
|
-
text
|
|
3046
|
-
]);
|
|
3047
|
-
return model;
|
|
3048
|
-
};
|
|
3049
|
-
var createModel = (props) => {
|
|
3050
|
-
const { text } = props;
|
|
3051
|
-
if (isAutomergeObject(text)) {
|
|
3052
|
-
return createAutomergeModel(props);
|
|
3053
|
-
} else if (text?.doc) {
|
|
3054
|
-
return createYjsModel(props);
|
|
3055
|
-
} else {
|
|
3056
|
-
return void 0;
|
|
3057
|
-
}
|
|
3058
|
-
};
|
|
3059
2936
|
export {
|
|
3060
2937
|
AwarenessProvider,
|
|
3061
2938
|
BaseTextEditor,
|
|
@@ -3067,7 +2944,6 @@ export {
|
|
|
3067
2944
|
SpaceAwarenessProvider,
|
|
3068
2945
|
TextEditor,
|
|
3069
2946
|
TextKind,
|
|
3070
|
-
YAwarenessProvider,
|
|
3071
2947
|
YText,
|
|
3072
2948
|
YXmlFragment,
|
|
3073
2949
|
autocomplete,
|
|
@@ -3079,14 +2955,13 @@ export {
|
|
|
3079
2955
|
code2 as code,
|
|
3080
2956
|
codeTheme,
|
|
3081
2957
|
comments,
|
|
3082
|
-
createAutomergeModel,
|
|
3083
|
-
createYjsModel,
|
|
3084
2958
|
defaultMarkdownSlots,
|
|
3085
2959
|
defaultOptions,
|
|
3086
2960
|
defaultSlots,
|
|
3087
2961
|
defaultTextSlots,
|
|
3088
2962
|
defaultTheme,
|
|
3089
2963
|
getToken,
|
|
2964
|
+
heading2 as heading,
|
|
3090
2965
|
hr,
|
|
3091
2966
|
image,
|
|
3092
2967
|
link,
|
|
@@ -3108,9 +2983,8 @@ export {
|
|
|
3108
2983
|
tasklist,
|
|
3109
2984
|
textTheme,
|
|
3110
2985
|
typewriter,
|
|
3111
|
-
useAwareness,
|
|
3112
2986
|
useComments,
|
|
3113
|
-
|
|
3114
|
-
|
|
2987
|
+
useTextEditor,
|
|
2988
|
+
useTextModel
|
|
3115
2989
|
};
|
|
3116
2990
|
//# sourceMappingURL=index.mjs.map
|