@dxos/react-ui-editor 0.3.11-main.8a2cfe6 → 0.3.11-main.8a9dd1e
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 +305 -385
- 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 +6 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +12 -17
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +6 -6
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/comments.stories.d.ts +26 -0
- package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/index.d.ts +1 -0
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
- package/dist/types/src/extensions/code.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +6 -2
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/{util → extensions}/cursor.d.ts +9 -1
- package/dist/types/src/extensions/cursor.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +1 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/tasklist.d.ts +5 -1
- package/dist/types/src/extensions/tasklist.d.ts.map +1 -1
- package/dist/types/src/extensions/yjs/cursor.d.ts +1 -1
- package/dist/types/src/extensions/yjs/cursor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextModel.d.ts +0 -5
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/hooks/yjs.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/dist/types/src/util.d.ts.map +1 -0
- package/package.json +24 -23
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +19 -16
- package/src/components/TextEditor/TextEditor.stories.tsx +12 -46
- package/src/components/TextEditor/TextEditor.tsx +68 -64
- package/src/components/TextEditor/comments.stories.tsx +329 -0
- package/src/extensions/autocomplete.ts +18 -17
- package/src/extensions/automerge/automerge.ts +2 -2
- package/src/extensions/automerge/cursor.ts +2 -1
- package/src/extensions/automerge/index.ts +1 -0
- package/src/extensions/awareness.ts +25 -32
- package/src/extensions/code.ts +10 -2
- package/src/extensions/comments.ts +86 -116
- package/src/extensions/cursor.ts +46 -0
- package/src/extensions/hr.ts +2 -2
- package/src/extensions/image.ts +2 -2
- package/src/extensions/index.ts +1 -0
- package/src/extensions/link.ts +4 -4
- package/src/extensions/markdown/highlight.ts +0 -8
- package/src/extensions/table.ts +6 -3
- package/src/extensions/tasklist.ts +53 -77
- package/src/extensions/yjs/cursor.ts +2 -1
- package/src/extensions/yjs/yjs.test.ts +1 -1
- package/src/extensions/yjs/yjs.ts +2 -2
- package/src/hooks/useTextModel.ts +4 -7
- package/src/hooks/yjs.ts +1 -23
- package/src/index.ts +2 -0
- package/src/styles/markdown.ts +0 -2
- package/src/themes/default.ts +17 -50
- package/dist/types/src/util/cursor.d.ts.map +0 -1
- package/dist/types/src/util/index.d.ts +0 -3
- package/dist/types/src/util/index.d.ts.map +0 -1
- package/dist/types/src/util/util.d.ts.map +0 -1
- package/src/util/cursor.ts +0 -29
- package/src/util/index.ts +0 -6
- /package/dist/types/src/{util/util.d.ts → util.d.ts} +0 -0
- /package/src/{util/util.ts → util.ts} +0 -0
|
@@ -11,40 +11,41 @@ import { EditorView as EditorView12 } 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, useImperativeHandle, useState } from "react";
|
|
14
|
+
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState, useRef } from "react";
|
|
15
15
|
import { generateName } from "@dxos/display-name";
|
|
16
16
|
import { useThemeContext } from "@dxos/react-ui";
|
|
17
17
|
import { getColorForValue, inputSurface, 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";
|
|
21
|
+
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
21
22
|
import { keymap } from "@codemirror/view";
|
|
22
23
|
var autocomplete = ({ onSearch }) => {
|
|
23
24
|
return [
|
|
24
25
|
// https://codemirror.net/docs/ref/#view.keymap
|
|
25
26
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
|
27
|
+
// TODO(burdon): Set custom keymap.
|
|
26
28
|
keymap.of(completionKeymap),
|
|
27
29
|
// https://codemirror.net/examples/autocompletion
|
|
28
30
|
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
|
29
31
|
autocompletion({
|
|
30
|
-
|
|
31
|
-
// defaultKeymap: false,
|
|
32
|
+
defaultKeymap: false,
|
|
32
33
|
// Don't start unless key press.
|
|
33
|
-
activateOnTyping: false
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
from: match.from,
|
|
44
|
-
options: onSearch(match.text.toLowerCase())
|
|
45
|
-
};
|
|
34
|
+
activateOnTyping: false
|
|
35
|
+
}),
|
|
36
|
+
// TODO(burdon): Option to create new page?
|
|
37
|
+
// TODO(burdon): Optional decoration via addToOptions
|
|
38
|
+
markdownLanguage.data.of({
|
|
39
|
+
autocomplete: (context) => {
|
|
40
|
+
const match = context.matchBefore(/\w*/);
|
|
41
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
42
|
+
return null;
|
|
46
43
|
}
|
|
47
|
-
|
|
44
|
+
return {
|
|
45
|
+
from: match.from,
|
|
46
|
+
options: onSearch(match.text.toLowerCase())
|
|
47
|
+
};
|
|
48
|
+
}
|
|
48
49
|
})
|
|
49
50
|
];
|
|
50
51
|
};
|
|
@@ -273,30 +274,39 @@ var PatchSemaphore = class {
|
|
|
273
274
|
}
|
|
274
275
|
};
|
|
275
276
|
|
|
276
|
-
// packages/ui/react-ui-editor/src/
|
|
277
|
+
// packages/ui/react-ui-editor/src/extensions/cursor.ts
|
|
277
278
|
import { Facet } from "@codemirror/state";
|
|
278
|
-
var
|
|
279
|
+
var defaultCursorConverter = {
|
|
279
280
|
toCursor: (position) => position.toString(),
|
|
280
281
|
fromCursor: (cursor) => parseInt(cursor)
|
|
281
282
|
};
|
|
282
|
-
var
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
// packages/ui/react-ui-editor/src/util/util.ts
|
|
287
|
-
import { log } from "@dxos/log";
|
|
288
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/util.ts";
|
|
289
|
-
var callbackWrapper = (fn) => (...args) => {
|
|
290
|
-
try {
|
|
291
|
-
return fn(...args);
|
|
292
|
-
} catch (error) {
|
|
293
|
-
log.catch(error, void 0, {
|
|
294
|
-
F: __dxlog_file,
|
|
295
|
-
L: 16,
|
|
296
|
-
S: void 0,
|
|
297
|
-
C: (f, a) => f(...a)
|
|
283
|
+
var Cursor = class {
|
|
284
|
+
static {
|
|
285
|
+
this.converter = Facet.define({
|
|
286
|
+
combine: (providers) => providers[0] ?? defaultCursorConverter
|
|
298
287
|
});
|
|
299
288
|
}
|
|
289
|
+
static {
|
|
290
|
+
this.getCursorFromRange = (cursorConverter3, range) => {
|
|
291
|
+
const from = cursorConverter3.toCursor(range.from);
|
|
292
|
+
const to = cursorConverter3.toCursor(range.to, -1);
|
|
293
|
+
return [
|
|
294
|
+
from,
|
|
295
|
+
to
|
|
296
|
+
].join(":");
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
static {
|
|
300
|
+
this.getRangeFromCursor = (cursorConverter3, cursor) => {
|
|
301
|
+
const parts = cursor.split(":");
|
|
302
|
+
const from = cursorConverter3.fromCursor(parts[0]);
|
|
303
|
+
const to = cursorConverter3.fromCursor(parts[1]);
|
|
304
|
+
return from !== void 0 && to !== void 0 ? {
|
|
305
|
+
from,
|
|
306
|
+
to
|
|
307
|
+
} : void 0;
|
|
308
|
+
};
|
|
309
|
+
}
|
|
300
310
|
};
|
|
301
311
|
|
|
302
312
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
@@ -355,7 +365,7 @@ var automerge3 = ({ handle, path }) => {
|
|
|
355
365
|
});
|
|
356
366
|
return {
|
|
357
367
|
extension: [
|
|
358
|
-
|
|
368
|
+
Cursor.converter.of(cursorConverter(handle, path)),
|
|
359
369
|
semaphoreFacet.of(semaphore),
|
|
360
370
|
stateField,
|
|
361
371
|
viewPlugin
|
|
@@ -397,7 +407,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
397
407
|
this._ctx = new Context();
|
|
398
408
|
this._lastAnchor = void 0;
|
|
399
409
|
this._lastHead = void 0;
|
|
400
|
-
this._cursorConverter = view.state.facet(
|
|
410
|
+
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
401
411
|
this._provider = view.state.facet(AwarenessProvider);
|
|
402
412
|
this._provider.open();
|
|
403
413
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
@@ -452,7 +462,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
452
462
|
attributes: {
|
|
453
463
|
style: `background-color: ${lightColor}`
|
|
454
464
|
},
|
|
455
|
-
class: "cm-
|
|
465
|
+
class: "cm-collab-selection"
|
|
456
466
|
})
|
|
457
467
|
});
|
|
458
468
|
} else {
|
|
@@ -463,7 +473,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
463
473
|
attributes: {
|
|
464
474
|
style: `background-color: ${color}`
|
|
465
475
|
},
|
|
466
|
-
class: "cm-
|
|
476
|
+
class: "cm-collab-selection"
|
|
467
477
|
})
|
|
468
478
|
});
|
|
469
479
|
decorations.push({
|
|
@@ -473,7 +483,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
473
483
|
attributes: {
|
|
474
484
|
style: `background-color: ${color}`
|
|
475
485
|
},
|
|
476
|
-
class: "cm-
|
|
486
|
+
class: "cm-collab-selection"
|
|
477
487
|
})
|
|
478
488
|
});
|
|
479
489
|
for (let i = startLine.number + 1; i < endLine.number; i++) {
|
|
@@ -484,7 +494,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
484
494
|
value: Decoration.line({
|
|
485
495
|
attributes: {
|
|
486
496
|
style: `background-color: ${color}`,
|
|
487
|
-
class: "cm-
|
|
497
|
+
class: "cm-collab-selectionLine"
|
|
488
498
|
}
|
|
489
499
|
})
|
|
490
500
|
});
|
|
@@ -504,23 +514,21 @@ var RemoteSelectionsDecorator = class {
|
|
|
504
514
|
}
|
|
505
515
|
};
|
|
506
516
|
var RemoteCaretWidget = class extends WidgetType {
|
|
507
|
-
constructor(
|
|
517
|
+
constructor(_name, _color) {
|
|
508
518
|
super();
|
|
509
|
-
this.
|
|
510
|
-
this.
|
|
511
|
-
this.name = name;
|
|
512
|
-
this.color = color;
|
|
519
|
+
this._name = _name;
|
|
520
|
+
this._color = _color;
|
|
513
521
|
}
|
|
514
522
|
toDOM() {
|
|
515
523
|
const span = document.createElement("span");
|
|
516
|
-
span.className = "cm-
|
|
517
|
-
span.style.backgroundColor = this.
|
|
518
|
-
span.style.borderColor = this.
|
|
524
|
+
span.className = "cm-collab-selectionCaret";
|
|
525
|
+
span.style.backgroundColor = this._color;
|
|
526
|
+
span.style.borderColor = this._color;
|
|
519
527
|
const dot = document.createElement("div");
|
|
520
|
-
dot.className = "cm-
|
|
528
|
+
dot.className = "cm-collab-selectionCaretDot";
|
|
521
529
|
const info = document.createElement("div");
|
|
522
|
-
info.className = "cm-
|
|
523
|
-
info.innerText = this.
|
|
530
|
+
info.className = "cm-collab-selectionInfo";
|
|
531
|
+
info.innerText = this._name;
|
|
524
532
|
span.appendChild(document.createTextNode("\u2060"));
|
|
525
533
|
span.appendChild(dot);
|
|
526
534
|
span.appendChild(document.createTextNode("\u2060"));
|
|
@@ -528,15 +536,12 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
|
528
536
|
span.appendChild(document.createTextNode("\u2060"));
|
|
529
537
|
return span;
|
|
530
538
|
}
|
|
531
|
-
eq(widget) {
|
|
532
|
-
return widget.color === this.color;
|
|
533
|
-
}
|
|
534
|
-
compare(widget) {
|
|
535
|
-
return widget.color === this.color;
|
|
536
|
-
}
|
|
537
539
|
updateDOM() {
|
|
538
540
|
return false;
|
|
539
541
|
}
|
|
542
|
+
eq(widget) {
|
|
543
|
+
return widget._color === this._color;
|
|
544
|
+
}
|
|
540
545
|
get estimatedHeight() {
|
|
541
546
|
return -1;
|
|
542
547
|
}
|
|
@@ -545,12 +550,12 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
|
545
550
|
}
|
|
546
551
|
};
|
|
547
552
|
var styles = EditorView.baseTheme({
|
|
548
|
-
".cm-
|
|
549
|
-
".cm-
|
|
553
|
+
".cm-collab-selection": {},
|
|
554
|
+
".cm-collab-selectionLine": {
|
|
550
555
|
padding: 0,
|
|
551
556
|
margin: "0px 2px 0px 4px"
|
|
552
557
|
},
|
|
553
|
-
".cm-
|
|
558
|
+
".cm-collab-selectionCaret": {
|
|
554
559
|
position: "relative",
|
|
555
560
|
borderLeft: "1px solid black",
|
|
556
561
|
borderRight: "1px solid black",
|
|
@@ -559,7 +564,7 @@ var styles = EditorView.baseTheme({
|
|
|
559
564
|
boxSizing: "border-box",
|
|
560
565
|
display: "inline"
|
|
561
566
|
},
|
|
562
|
-
".cm-
|
|
567
|
+
".cm-collab-selectionCaretDot": {
|
|
563
568
|
borderRadius: "50%",
|
|
564
569
|
position: "absolute",
|
|
565
570
|
width: ".4em",
|
|
@@ -570,11 +575,11 @@ var styles = EditorView.baseTheme({
|
|
|
570
575
|
transition: "transform .3s ease-in-out",
|
|
571
576
|
boxSizing: "border-box"
|
|
572
577
|
},
|
|
573
|
-
".cm-
|
|
578
|
+
".cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot": {
|
|
574
579
|
transformOrigin: "bottom center",
|
|
575
580
|
transform: "scale(0)"
|
|
576
581
|
},
|
|
577
|
-
".cm-
|
|
582
|
+
".cm-collab-selectionInfo": {
|
|
578
583
|
position: "absolute",
|
|
579
584
|
top: "-1.05em",
|
|
580
585
|
left: "-1px",
|
|
@@ -595,7 +600,7 @@ var styles = EditorView.baseTheme({
|
|
|
595
600
|
transitionDelay: "0s",
|
|
596
601
|
whiteSpace: "nowrap"
|
|
597
602
|
},
|
|
598
|
-
".cm-
|
|
603
|
+
".cm-collab-selectionCaret:hover > .cm-collab-selectionInfo": {
|
|
599
604
|
opacity: 1,
|
|
600
605
|
transitionDelay: "0s"
|
|
601
606
|
}
|
|
@@ -622,7 +627,7 @@ var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
|
|
|
622
627
|
import { EditorView as EditorView3, keymap as keymap2 } from "@codemirror/view";
|
|
623
628
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
624
629
|
import { invariant } from "@dxos/invariant";
|
|
625
|
-
var
|
|
630
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
626
631
|
var defaultOptions = {
|
|
627
632
|
effect: 2,
|
|
628
633
|
maxParticles: 200,
|
|
@@ -749,7 +754,7 @@ var Blaster = class {
|
|
|
749
754
|
}
|
|
750
755
|
initialize() {
|
|
751
756
|
invariant(!this._canvas && !this._ctx, void 0, {
|
|
752
|
-
F:
|
|
757
|
+
F: __dxlog_file,
|
|
753
758
|
L: 138,
|
|
754
759
|
S: this,
|
|
755
760
|
A: [
|
|
@@ -786,7 +791,7 @@ var Blaster = class {
|
|
|
786
791
|
}
|
|
787
792
|
start() {
|
|
788
793
|
invariant(this._canvas && this._ctx, void 0, {
|
|
789
|
-
F:
|
|
794
|
+
F: __dxlog_file,
|
|
790
795
|
L: 177,
|
|
791
796
|
S: this,
|
|
792
797
|
A: [
|
|
@@ -1056,7 +1061,7 @@ var getLineRange = (lines, from, to) => {
|
|
|
1056
1061
|
var code2 = () => {
|
|
1057
1062
|
const getDecorations = (view) => {
|
|
1058
1063
|
const decorations = [];
|
|
1059
|
-
if (view.state.readOnly) {
|
|
1064
|
+
if (!view.hasFocus || view.state.readOnly) {
|
|
1060
1065
|
const text = view.state.doc.sliceString(0);
|
|
1061
1066
|
const matches = text.matchAll(CODE_REGEX);
|
|
1062
1067
|
const blocks = view.viewportLineBlocks;
|
|
@@ -1075,10 +1080,15 @@ var code2 = () => {
|
|
|
1075
1080
|
return [
|
|
1076
1081
|
ViewPlugin3.fromClass(class {
|
|
1077
1082
|
constructor(view) {
|
|
1083
|
+
this.hasFocus = false;
|
|
1078
1084
|
this.decorations = getDecorations(view);
|
|
1079
1085
|
}
|
|
1080
1086
|
update(update2) {
|
|
1081
|
-
if (
|
|
1087
|
+
if (
|
|
1088
|
+
// TODO(burdon): Generalize for other extensions.
|
|
1089
|
+
this.hasFocus !== update2.view.hasFocus || update2.startState.readOnly !== update2.view.state.readOnly || update2.docChanged || update2.viewportChanged
|
|
1090
|
+
) {
|
|
1091
|
+
this.hasFocus = update2.view.hasFocus;
|
|
1082
1092
|
this.decorations = getDecorations(update2.view);
|
|
1083
1093
|
}
|
|
1084
1094
|
}
|
|
@@ -1091,23 +1101,32 @@ var code2 = () => {
|
|
|
1091
1101
|
|
|
1092
1102
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1093
1103
|
import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1094
|
-
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView5
|
|
1104
|
+
import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView5 } from "@codemirror/view";
|
|
1095
1105
|
import sortBy from "lodash.sortby";
|
|
1096
1106
|
import { debounce } from "@dxos/async";
|
|
1097
1107
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1098
1108
|
import { log as log2 } from "@dxos/log";
|
|
1099
1109
|
import { nonNullable } from "@dxos/util";
|
|
1110
|
+
|
|
1111
|
+
// packages/ui/react-ui-editor/src/util.ts
|
|
1112
|
+
import { log } from "@dxos/log";
|
|
1113
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
|
|
1114
|
+
var callbackWrapper = (fn) => (...args) => {
|
|
1115
|
+
try {
|
|
1116
|
+
return fn(...args);
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
log.catch(error, void 0, {
|
|
1119
|
+
F: __dxlog_file2,
|
|
1120
|
+
L: 16,
|
|
1121
|
+
S: void 0,
|
|
1122
|
+
C: (f, a) => f(...a)
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
};
|
|
1126
|
+
|
|
1127
|
+
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1100
1128
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1101
1129
|
var styles3 = EditorView5.baseTheme({
|
|
1102
|
-
"& .cm-bookmark": {
|
|
1103
|
-
cursor: "pointer",
|
|
1104
|
-
margin: "4px",
|
|
1105
|
-
padding: "4px",
|
|
1106
|
-
backgroundColor: "yellow"
|
|
1107
|
-
},
|
|
1108
|
-
"& .cm-bookmark-selected": {
|
|
1109
|
-
backgroundColor: "orange"
|
|
1110
|
-
},
|
|
1111
1130
|
"& .cm-comment": {
|
|
1112
1131
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
1113
1132
|
},
|
|
@@ -1146,7 +1165,7 @@ var commentsStateField = StateField2.define({
|
|
|
1146
1165
|
ranges: []
|
|
1147
1166
|
}),
|
|
1148
1167
|
update: (value, tr) => {
|
|
1149
|
-
const cursorConverter3 = tr.state.facet(
|
|
1168
|
+
const cursorConverter3 = tr.state.facet(Cursor.converter);
|
|
1150
1169
|
for (const effect of tr.effects) {
|
|
1151
1170
|
if (effect.is(setSelection)) {
|
|
1152
1171
|
return {
|
|
@@ -1157,7 +1176,7 @@ var commentsStateField = StateField2.define({
|
|
|
1157
1176
|
if (effect.is(setCommentRange)) {
|
|
1158
1177
|
const { comments: comments2 } = effect.value;
|
|
1159
1178
|
const ranges = comments2.map((comment) => {
|
|
1160
|
-
const range = getRangeFromCursor(cursorConverter3, comment.cursor);
|
|
1179
|
+
const range = Cursor.getRangeFromCursor(cursorConverter3, comment.cursor);
|
|
1161
1180
|
return range && {
|
|
1162
1181
|
...comment,
|
|
1163
1182
|
...range
|
|
@@ -1195,42 +1214,68 @@ var highlightDecorations = EditorView5.decorations.compute([
|
|
|
1195
1214
|
}).filter(nonNullable) ?? [];
|
|
1196
1215
|
return Decoration3.set(decorations);
|
|
1197
1216
|
});
|
|
1198
|
-
var
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
return this._anchor === other._anchor && this._id === other._id;
|
|
1216
|
-
}
|
|
1217
|
-
toDOM() {
|
|
1218
|
-
const span = document.createElement("span");
|
|
1219
|
-
span.className = "cm-bookmark";
|
|
1220
|
-
span.textContent = "\u203B";
|
|
1221
|
-
if (this._handleClick) {
|
|
1222
|
-
span.onclick = () => this._handleClick();
|
|
1217
|
+
var trackPastedComments = (onMove) => {
|
|
1218
|
+
let tracked = null;
|
|
1219
|
+
const registerCopy = (event, view) => {
|
|
1220
|
+
const comments2 = view.state.field(commentsStateField);
|
|
1221
|
+
const { main } = view.state.selection;
|
|
1222
|
+
const inSel = comments2.ranges.filter((range) => range.from >= main.from && range.to <= main.to && range.from < range.to);
|
|
1223
|
+
if (!inSel.length) {
|
|
1224
|
+
tracked = null;
|
|
1225
|
+
} else {
|
|
1226
|
+
tracked = {
|
|
1227
|
+
text: view.state.doc.slice(main.from, main.to),
|
|
1228
|
+
comments: inSel.map((range) => ({
|
|
1229
|
+
from: range.from - main.from,
|
|
1230
|
+
to: range.to - main.from,
|
|
1231
|
+
id: range.id
|
|
1232
|
+
}))
|
|
1233
|
+
};
|
|
1223
1234
|
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1235
|
+
};
|
|
1236
|
+
return [
|
|
1237
|
+
EditorView5.domEventHandlers({
|
|
1238
|
+
cut: registerCopy,
|
|
1239
|
+
copy: registerCopy
|
|
1240
|
+
}),
|
|
1241
|
+
EditorView5.updateListener.of((update2) => {
|
|
1242
|
+
if (tracked) {
|
|
1243
|
+
const paste = update2.transactions.find((tr) => tr.isUserEvent("input.paste"));
|
|
1244
|
+
if (paste) {
|
|
1245
|
+
let found = -1;
|
|
1246
|
+
paste.changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
1247
|
+
if (text.eq(tracked.text)) {
|
|
1248
|
+
for (let i = update2.transactions.indexOf(paste) + 1; i < update2.transactions.length; i++) {
|
|
1249
|
+
fromB = update2.transactions[i].changes.mapPos(fromB);
|
|
1250
|
+
}
|
|
1251
|
+
found = fromB;
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
if (found > -1) {
|
|
1255
|
+
const active = update2.view.state.field(commentsStateField).ranges;
|
|
1256
|
+
for (const moved of tracked.comments) {
|
|
1257
|
+
if (active.some((range) => range.id === moved.id && range.from === range.to)) {
|
|
1258
|
+
onMove(moved.id, Cursor.getCursorFromRange(update2.view.state.facet(Cursor.converter), {
|
|
1259
|
+
from: found + moved.from,
|
|
1260
|
+
to: found + moved.to
|
|
1261
|
+
}));
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
tracked = null;
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
})
|
|
1269
|
+
];
|
|
1226
1270
|
};
|
|
1227
1271
|
var comments = (options = {}) => {
|
|
1272
|
+
const { key: shortcut = "meta-'" } = options;
|
|
1228
1273
|
const handleSelect = debounce((state) => options.onSelect?.(state), 200);
|
|
1229
1274
|
const createCommentThread = (view) => {
|
|
1230
|
-
const cursorConverter3 = view.state.facet(
|
|
1275
|
+
const cursorConverter3 = view.state.facet(Cursor.converter);
|
|
1231
1276
|
invariant2(options.onCreate, void 0, {
|
|
1232
1277
|
F: __dxlog_file3,
|
|
1233
|
-
L:
|
|
1278
|
+
L: 240,
|
|
1234
1279
|
S: void 0,
|
|
1235
1280
|
A: [
|
|
1236
1281
|
"options.onCreate",
|
|
@@ -1241,12 +1286,12 @@ var comments = (options = {}) => {
|
|
|
1241
1286
|
if (from === to) {
|
|
1242
1287
|
return false;
|
|
1243
1288
|
}
|
|
1244
|
-
const
|
|
1289
|
+
const cursor = Cursor.getCursorFromRange(cursorConverter3, {
|
|
1245
1290
|
from,
|
|
1246
1291
|
to
|
|
1247
1292
|
});
|
|
1248
|
-
if (
|
|
1249
|
-
const id = callbackWrapper(options.onCreate)(
|
|
1293
|
+
if (cursor) {
|
|
1294
|
+
const id = callbackWrapper(options.onCreate)(cursor, view.coordsAtPos(from));
|
|
1250
1295
|
if (id) {
|
|
1251
1296
|
view.dispatch({
|
|
1252
1297
|
effects: setSelection.of({
|
|
@@ -1273,35 +1318,7 @@ var comments = (options = {}) => {
|
|
|
1273
1318
|
}
|
|
1274
1319
|
return false;
|
|
1275
1320
|
};
|
|
1276
|
-
const bookmarksViewPlugin = ViewPlugin4.fromClass(class BookmarkViewPlugin {
|
|
1277
|
-
static {
|
|
1278
|
-
// Match markdown footnotes (option).
|
|
1279
|
-
// https://www.markdownguide.org/extended-syntax/#footnotes
|
|
1280
|
-
this.bookmarkMatcher = new MatchDecorator({
|
|
1281
|
-
regexp: /\[\^(\w+)\]/g,
|
|
1282
|
-
decoration: (match, view, pos) => {
|
|
1283
|
-
const id = match[1];
|
|
1284
|
-
return Decoration3.replace({
|
|
1285
|
-
id,
|
|
1286
|
-
widget: new BookmarkWidget(pos, id)
|
|
1287
|
-
});
|
|
1288
|
-
}
|
|
1289
|
-
});
|
|
1290
|
-
}
|
|
1291
|
-
constructor(view) {
|
|
1292
|
-
this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.createDeco(view);
|
|
1293
|
-
}
|
|
1294
|
-
update(update2) {
|
|
1295
|
-
this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.updateDeco(update2, this.bookmarks);
|
|
1296
|
-
}
|
|
1297
|
-
}, {
|
|
1298
|
-
decorations: (instance) => instance.bookmarks,
|
|
1299
|
-
provide: (plugin) => EditorView5.atomicRanges.of((view) => {
|
|
1300
|
-
return view.plugin(plugin)?.bookmarks || Decoration3.none;
|
|
1301
|
-
})
|
|
1302
|
-
});
|
|
1303
1321
|
return [
|
|
1304
|
-
bookmarksViewPlugin,
|
|
1305
1322
|
commentsStateField,
|
|
1306
1323
|
highlightDecorations,
|
|
1307
1324
|
styles3,
|
|
@@ -1310,7 +1327,7 @@ var comments = (options = {}) => {
|
|
|
1310
1327
|
//
|
|
1311
1328
|
options.onCreate ? keymap3.of([
|
|
1312
1329
|
{
|
|
1313
|
-
key:
|
|
1330
|
+
key: shortcut,
|
|
1314
1331
|
run: callbackWrapper(createCommentThread)
|
|
1315
1332
|
}
|
|
1316
1333
|
]) : [],
|
|
@@ -1327,7 +1344,7 @@ var comments = (options = {}) => {
|
|
|
1327
1344
|
above: true,
|
|
1328
1345
|
create: () => {
|
|
1329
1346
|
const el = document.createElement("div");
|
|
1330
|
-
options.onHover?.(el);
|
|
1347
|
+
options.onHover?.(el, shortcut);
|
|
1331
1348
|
return {
|
|
1332
1349
|
dom: el,
|
|
1333
1350
|
offset: {
|
|
@@ -1348,27 +1365,27 @@ var comments = (options = {}) => {
|
|
|
1348
1365
|
// TODO(burdon): Is there a better (finer grained) way to do this?
|
|
1349
1366
|
//
|
|
1350
1367
|
EditorView5.updateListener.of(({ view, state, changes }) => {
|
|
1351
|
-
const cursorConverter3 = view.state.facet(
|
|
1368
|
+
const cursorConverter3 = view.state.facet(Cursor.converter);
|
|
1352
1369
|
{
|
|
1353
1370
|
let mod = false;
|
|
1354
1371
|
const { active, ranges } = state.field(commentsStateField);
|
|
1355
1372
|
changes.iterChanges((from, to, from2, to2) => {
|
|
1356
1373
|
ranges.forEach((range) => {
|
|
1357
1374
|
if (from2 === to2) {
|
|
1358
|
-
const newRange = getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1375
|
+
const newRange = Cursor.getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1359
1376
|
if (!newRange || newRange.to - newRange.from === 0) {
|
|
1360
1377
|
log2.info("deleted comment", {
|
|
1361
1378
|
thread: range.id
|
|
1362
1379
|
}, {
|
|
1363
1380
|
F: __dxlog_file3,
|
|
1364
|
-
L:
|
|
1381
|
+
L: 337,
|
|
1365
1382
|
S: void 0,
|
|
1366
1383
|
C: (f, a) => f(...a)
|
|
1367
1384
|
});
|
|
1368
1385
|
}
|
|
1369
1386
|
}
|
|
1370
1387
|
if (from <= range.to) {
|
|
1371
|
-
const newRange = getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1388
|
+
const newRange = Cursor.getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1372
1389
|
Object.assign(range, newRange);
|
|
1373
1390
|
mod = true;
|
|
1374
1391
|
}
|
|
@@ -1414,29 +1431,13 @@ var comments = (options = {}) => {
|
|
|
1414
1431
|
});
|
|
1415
1432
|
}
|
|
1416
1433
|
}
|
|
1417
|
-
})
|
|
1434
|
+
}),
|
|
1435
|
+
options.onMove ? trackPastedComments(options.onMove) : []
|
|
1418
1436
|
];
|
|
1419
1437
|
};
|
|
1420
|
-
var getCursorFromRange = (cursorConverter3, range) => {
|
|
1421
|
-
const from = cursorConverter3.toCursor(range.from);
|
|
1422
|
-
const to = cursorConverter3.toCursor(range.to, -1);
|
|
1423
|
-
return [
|
|
1424
|
-
from,
|
|
1425
|
-
to
|
|
1426
|
-
].join(":");
|
|
1427
|
-
};
|
|
1428
|
-
var getRangeFromCursor = (cursorConverter3, cursor) => {
|
|
1429
|
-
const parts = cursor.split(":");
|
|
1430
|
-
const from = cursorConverter3.fromCursor(parts[0]);
|
|
1431
|
-
const to = cursorConverter3.fromCursor(parts[1]);
|
|
1432
|
-
return from !== void 0 && to !== void 0 ? {
|
|
1433
|
-
from,
|
|
1434
|
-
to
|
|
1435
|
-
} : void 0;
|
|
1436
|
-
};
|
|
1437
1438
|
|
|
1438
1439
|
// packages/ui/react-ui-editor/src/extensions/hr.ts
|
|
1439
|
-
import { Decoration as Decoration4, EditorView as EditorView6, MatchDecorator
|
|
1440
|
+
import { Decoration as Decoration4, EditorView as EditorView6, MatchDecorator, ViewPlugin as ViewPlugin4, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1440
1441
|
var styles4 = EditorView6.baseTheme({
|
|
1441
1442
|
"& .cm-hr": {
|
|
1442
1443
|
// TODO(burdon): ???
|
|
@@ -1444,7 +1445,7 @@ var styles4 = EditorView6.baseTheme({
|
|
|
1444
1445
|
borderBottom: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
1445
1446
|
}
|
|
1446
1447
|
});
|
|
1447
|
-
var HorizontalRuleWidget = class extends
|
|
1448
|
+
var HorizontalRuleWidget = class extends WidgetType2 {
|
|
1448
1449
|
constructor(_pos) {
|
|
1449
1450
|
super();
|
|
1450
1451
|
this._pos = _pos;
|
|
@@ -1458,7 +1459,7 @@ var HorizontalRuleWidget = class extends WidgetType3 {
|
|
|
1458
1459
|
return el;
|
|
1459
1460
|
}
|
|
1460
1461
|
};
|
|
1461
|
-
var placeholderMatcher = new
|
|
1462
|
+
var placeholderMatcher = new MatchDecorator({
|
|
1462
1463
|
regexp: /^---$/g,
|
|
1463
1464
|
decoration: (match, view, pos) => Decoration4.replace({
|
|
1464
1465
|
widget: new HorizontalRuleWidget(pos)
|
|
@@ -1466,7 +1467,7 @@ var placeholderMatcher = new MatchDecorator2({
|
|
|
1466
1467
|
});
|
|
1467
1468
|
var hr = () => [
|
|
1468
1469
|
styles4,
|
|
1469
|
-
|
|
1470
|
+
ViewPlugin4.fromClass(class {
|
|
1470
1471
|
constructor(view) {
|
|
1471
1472
|
this.rules = placeholderMatcher.createDeco(view);
|
|
1472
1473
|
}
|
|
@@ -1485,7 +1486,7 @@ var hr = () => [
|
|
|
1485
1486
|
// packages/ui/react-ui-editor/src/extensions/image.ts
|
|
1486
1487
|
import { syntaxTree } from "@codemirror/language";
|
|
1487
1488
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
1488
|
-
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as
|
|
1489
|
+
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1489
1490
|
var image = (options = {}) => {
|
|
1490
1491
|
return StateField3.define({
|
|
1491
1492
|
create: (state) => {
|
|
@@ -1537,7 +1538,7 @@ var buildDecorations = (from, to, state) => {
|
|
|
1537
1538
|
});
|
|
1538
1539
|
return decorations;
|
|
1539
1540
|
};
|
|
1540
|
-
var ImageWidget = class extends
|
|
1541
|
+
var ImageWidget = class extends WidgetType3 {
|
|
1541
1542
|
constructor(_url) {
|
|
1542
1543
|
super();
|
|
1543
1544
|
this._url = _url;
|
|
@@ -1557,11 +1558,11 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
1557
1558
|
// packages/ui/react-ui-editor/src/extensions/link.ts
|
|
1558
1559
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1559
1560
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
1560
|
-
import { Decoration as Decoration6, WidgetType as
|
|
1561
|
+
import { Decoration as Decoration6, WidgetType as WidgetType4, hoverTooltip as hoverTooltip2, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
1561
1562
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1562
1563
|
var link = (options = {}) => {
|
|
1563
1564
|
const extensions = [
|
|
1564
|
-
|
|
1565
|
+
ViewPlugin5.fromClass(class {
|
|
1565
1566
|
constructor(view) {
|
|
1566
1567
|
this.decorations = buildDecorations2(view, options);
|
|
1567
1568
|
}
|
|
@@ -1612,7 +1613,7 @@ var link = (options = {}) => {
|
|
|
1612
1613
|
}
|
|
1613
1614
|
return extensions;
|
|
1614
1615
|
};
|
|
1615
|
-
var LinkButton = class extends
|
|
1616
|
+
var LinkButton = class extends WidgetType4 {
|
|
1616
1617
|
constructor(_url, _onAttach) {
|
|
1617
1618
|
super();
|
|
1618
1619
|
this._url = _url;
|
|
@@ -1627,7 +1628,7 @@ var LinkButton = class extends WidgetType5 {
|
|
|
1627
1628
|
return el;
|
|
1628
1629
|
}
|
|
1629
1630
|
};
|
|
1630
|
-
var LinkText = class extends
|
|
1631
|
+
var LinkText = class extends WidgetType4 {
|
|
1631
1632
|
constructor(_text, _url) {
|
|
1632
1633
|
super();
|
|
1633
1634
|
this._text = _text;
|
|
@@ -1708,7 +1709,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
1708
1709
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
1709
1710
|
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1710
1711
|
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1711
|
-
import { markdownLanguage as
|
|
1712
|
+
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
1712
1713
|
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
1713
1714
|
import { languages } from "@codemirror/language-data";
|
|
1714
1715
|
import { searchKeymap } from "@codemirror/search";
|
|
@@ -1717,7 +1718,7 @@ import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/the
|
|
|
1717
1718
|
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView9, highlightActiveLine, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
|
|
1718
1719
|
|
|
1719
1720
|
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
1720
|
-
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
1721
|
+
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
1721
1722
|
import { HighlightStyle } from "@codemirror/language";
|
|
1722
1723
|
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
1723
1724
|
import { Table } from "@lezer/markdown";
|
|
@@ -1727,7 +1728,6 @@ var markdownTags = {
|
|
|
1727
1728
|
CodeText: Tag.define(),
|
|
1728
1729
|
EmphasisMark: Tag.define(),
|
|
1729
1730
|
HeaderMark: Tag.define(),
|
|
1730
|
-
// HorizontalRule: Tag.define(),
|
|
1731
1731
|
InlineCode: Tag.define(),
|
|
1732
1732
|
LinkLabel: Tag.define(),
|
|
1733
1733
|
LinkReference: Tag.define(),
|
|
@@ -1891,12 +1891,6 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1891
1891
|
],
|
|
1892
1892
|
class: blockquote
|
|
1893
1893
|
},
|
|
1894
|
-
// TODO(burdon): Replace with extension.
|
|
1895
|
-
// {
|
|
1896
|
-
// tag: [markdownTags.HorizontalRule],
|
|
1897
|
-
// class: mx(horizontalRule, readonly && '-indent-[100rem]'),
|
|
1898
|
-
// },
|
|
1899
|
-
// TODO(burdon): Only if being edited.
|
|
1900
1894
|
{
|
|
1901
1895
|
tag: [
|
|
1902
1896
|
markdownTags.TableCell
|
|
@@ -1904,7 +1898,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1904
1898
|
class: "font-mono"
|
|
1905
1899
|
}
|
|
1906
1900
|
], {
|
|
1907
|
-
scope:
|
|
1901
|
+
scope: markdownLanguage2,
|
|
1908
1902
|
all: {
|
|
1909
1903
|
fontFamily: getToken("fontFamily.body", []).join(",")
|
|
1910
1904
|
}
|
|
@@ -1936,7 +1930,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
1936
1930
|
// NOTE: This extends the parser; it doesn't affect rendering.
|
|
1937
1931
|
// https://github.github.com/gfm
|
|
1938
1932
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
1939
|
-
base:
|
|
1933
|
+
base: markdownLanguage3,
|
|
1940
1934
|
// Languages for syntax highlighting fenced code blocks.
|
|
1941
1935
|
codeLanguages: languages,
|
|
1942
1936
|
// Parser extensions.
|
|
@@ -1990,7 +1984,7 @@ var mention = ({ onSearch }) => {
|
|
|
1990
1984
|
// packages/ui/react-ui-editor/src/extensions/table.ts
|
|
1991
1985
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1992
1986
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField4 } from "@codemirror/state";
|
|
1993
|
-
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as
|
|
1987
|
+
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
1994
1988
|
var table = (options = {}) => {
|
|
1995
1989
|
return StateField4.define({
|
|
1996
1990
|
create: (state) => update(state, options),
|
|
@@ -2040,7 +2034,6 @@ var update = (state, options) => {
|
|
|
2040
2034
|
tables.forEach((table2) => {
|
|
2041
2035
|
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
2042
2036
|
hide && builder.add(table2.from, table2.to, Decoration7.replace({
|
|
2043
|
-
block: true,
|
|
2044
2037
|
widget: new TableWidget(table2)
|
|
2045
2038
|
}));
|
|
2046
2039
|
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
@@ -2049,7 +2042,7 @@ var update = (state, options) => {
|
|
|
2049
2042
|
});
|
|
2050
2043
|
return builder.finish();
|
|
2051
2044
|
};
|
|
2052
|
-
var TableWidget = class extends
|
|
2045
|
+
var TableWidget = class extends WidgetType5 {
|
|
2053
2046
|
constructor(_table) {
|
|
2054
2047
|
super();
|
|
2055
2048
|
this._table = _table;
|
|
@@ -2081,90 +2074,91 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2081
2074
|
}
|
|
2082
2075
|
return table2;
|
|
2083
2076
|
}
|
|
2077
|
+
ignoreEvent(e) {
|
|
2078
|
+
return !/^mouse/.test(e.type);
|
|
2079
|
+
}
|
|
2084
2080
|
};
|
|
2085
2081
|
|
|
2086
2082
|
// packages/ui/react-ui-editor/src/extensions/tasklist.ts
|
|
2087
|
-
import {
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
}
|
|
2093
|
-
});
|
|
2094
|
-
var CheckboxWidget = class extends WidgetType7 {
|
|
2095
|
-
constructor(_checked, _indent, _onCheck) {
|
|
2083
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
2084
|
+
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
2085
|
+
import { EditorView as EditorView11, Decoration as Decoration8, WidgetType as WidgetType6, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
2086
|
+
var CheckboxWidget = class extends WidgetType6 {
|
|
2087
|
+
constructor(_checked) {
|
|
2096
2088
|
super();
|
|
2097
2089
|
this._checked = _checked;
|
|
2098
|
-
this._indent = _indent;
|
|
2099
|
-
this._onCheck = _onCheck;
|
|
2100
2090
|
}
|
|
2101
2091
|
eq(other) {
|
|
2102
|
-
return this._checked === other._checked
|
|
2092
|
+
return this._checked === other._checked;
|
|
2103
2093
|
}
|
|
2104
2094
|
toDOM(view) {
|
|
2105
|
-
const
|
|
2106
|
-
wrap.className = "cm-task-item";
|
|
2107
|
-
wrap.setAttribute("aria-hidden", "true");
|
|
2108
|
-
wrap.style.setProperty("margin-left", this._indent * 24 + "px");
|
|
2109
|
-
const input = wrap.appendChild(document.createElement("input"));
|
|
2095
|
+
const input = document.createElement("input");
|
|
2110
2096
|
input.type = "checkbox";
|
|
2111
2097
|
input.checked = this._checked;
|
|
2112
|
-
if (
|
|
2098
|
+
if (view.state.readOnly) {
|
|
2113
2099
|
input.setAttribute("disabled", "true");
|
|
2114
|
-
}
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2100
|
+
} else {
|
|
2101
|
+
input.onmousedown = (event) => {
|
|
2102
|
+
const pos = view.posAtDOM(input);
|
|
2103
|
+
const text = view.state.sliceDoc(pos, pos + 3);
|
|
2104
|
+
if (text === (this._checked ? "[x]" : "[ ]")) {
|
|
2105
|
+
view.dispatch({
|
|
2106
|
+
changes: {
|
|
2107
|
+
from: pos + 1,
|
|
2108
|
+
to: pos + 2,
|
|
2109
|
+
insert: this._checked ? " " : "x"
|
|
2110
|
+
}
|
|
2111
|
+
});
|
|
2112
|
+
event.preventDefault();
|
|
2113
|
+
}
|
|
2119
2114
|
};
|
|
2120
2115
|
}
|
|
2121
|
-
return
|
|
2116
|
+
return input;
|
|
2122
2117
|
}
|
|
2123
2118
|
ignoreEvent() {
|
|
2124
2119
|
return false;
|
|
2125
2120
|
}
|
|
2126
2121
|
};
|
|
2122
|
+
var checkedDeco = Decoration8.replace({
|
|
2123
|
+
widget: new CheckboxWidget(true)
|
|
2124
|
+
});
|
|
2125
|
+
var uncheckedDeco = Decoration8.replace({
|
|
2126
|
+
widget: new CheckboxWidget(false)
|
|
2127
|
+
});
|
|
2127
2128
|
var tasklist = (options = {}) => {
|
|
2128
|
-
|
|
2129
|
-
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
2130
|
-
decoration: (match, view, pos) => {
|
|
2131
|
-
const indent = Math.floor(match[1].length / 2);
|
|
2132
|
-
const checked = match[2] === "x" || match[2] === "X";
|
|
2133
|
-
return Decoration8.replace({
|
|
2134
|
-
widget: new CheckboxWidget(checked, indent, view.state.readOnly ? void 0 : (checked2) => {
|
|
2135
|
-
const idx = pos + match[0].indexOf("[") + 1;
|
|
2136
|
-
view.dispatch({
|
|
2137
|
-
changes: {
|
|
2138
|
-
from: idx,
|
|
2139
|
-
to: idx + 1,
|
|
2140
|
-
insert: checked2 ? "x" : " "
|
|
2141
|
-
},
|
|
2142
|
-
// TODO(burdon): Restore cursor position? More useful to move to end of line (can indent).
|
|
2143
|
-
selection: {
|
|
2144
|
-
anchor: idx + 3
|
|
2145
|
-
}
|
|
2146
|
-
});
|
|
2147
|
-
})
|
|
2148
|
-
});
|
|
2149
|
-
}
|
|
2150
|
-
});
|
|
2151
|
-
const tasks = ViewPlugin7.fromClass(class {
|
|
2129
|
+
return ViewPlugin6.fromClass(class {
|
|
2152
2130
|
constructor(view) {
|
|
2153
|
-
this.
|
|
2131
|
+
this.decorations = buildDecorations3(view);
|
|
2154
2132
|
}
|
|
2155
2133
|
update(update2) {
|
|
2156
|
-
|
|
2134
|
+
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
2135
|
+
this.decorations = buildDecorations3(update2.view);
|
|
2136
|
+
}
|
|
2157
2137
|
}
|
|
2158
2138
|
}, {
|
|
2159
|
-
decorations: (
|
|
2139
|
+
decorations: (v) => v.decorations,
|
|
2160
2140
|
provide: (plugin) => EditorView11.atomicRanges.of((view) => {
|
|
2161
|
-
return view.plugin(plugin)?.
|
|
2141
|
+
return view.plugin(plugin)?.decorations || Decoration8.none;
|
|
2162
2142
|
})
|
|
2163
2143
|
});
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2144
|
+
};
|
|
2145
|
+
var buildDecorations3 = (view) => {
|
|
2146
|
+
const builder = new RangeSetBuilder3();
|
|
2147
|
+
const { state } = view;
|
|
2148
|
+
const cursor = state.selection.main.head;
|
|
2149
|
+
for (const { from, to } of view.visibleRanges) {
|
|
2150
|
+
syntaxTree4(state).iterate({
|
|
2151
|
+
enter: (node) => {
|
|
2152
|
+
if (node.name === "TaskMarker" && (cursor < node.from || cursor > node.to)) {
|
|
2153
|
+
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2154
|
+
builder.add(node.from, node.to, checked ? checkedDeco : uncheckedDeco);
|
|
2155
|
+
}
|
|
2156
|
+
},
|
|
2157
|
+
from,
|
|
2158
|
+
to
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
return builder.finish();
|
|
2168
2162
|
};
|
|
2169
2163
|
|
|
2170
2164
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
@@ -2241,7 +2235,7 @@ var cursorConverter2 = (text) => ({
|
|
|
2241
2235
|
|
|
2242
2236
|
// packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
|
|
2243
2237
|
var yjs = (content, awareness2) => [
|
|
2244
|
-
|
|
2238
|
+
Cursor.converter.of(cursorConverter2(content)),
|
|
2245
2239
|
yCollab(content, awareness2)
|
|
2246
2240
|
];
|
|
2247
2241
|
|
|
@@ -2338,33 +2332,6 @@ var defaultTheme = {
|
|
|
2338
2332
|
backgroundColor: get3(tokens, "extend.colors.yellow.700")
|
|
2339
2333
|
},
|
|
2340
2334
|
//
|
|
2341
|
-
// collaboration
|
|
2342
|
-
// TODO(burdon): Review classnames (YJS dependent?) Note: e2e tests depend on this class.
|
|
2343
|
-
//
|
|
2344
|
-
"&light .cm-ySelection, &light .cm-yLineSelection": {
|
|
2345
|
-
mixBlendMode: "multiply"
|
|
2346
|
-
},
|
|
2347
|
-
"&dark .cm-ySelection, &dark .cm-yLineSelection": {
|
|
2348
|
-
mixBlendMode: "screen"
|
|
2349
|
-
},
|
|
2350
|
-
".cm-ySelectionInfo": {
|
|
2351
|
-
padding: "2px 4px",
|
|
2352
|
-
marginBlockStart: "-4px"
|
|
2353
|
-
},
|
|
2354
|
-
".cm-ySelection, & .cm-selectionMatch": {
|
|
2355
|
-
paddingBlockStart: ".15em",
|
|
2356
|
-
paddingBlockEnd: ".15em"
|
|
2357
|
-
},
|
|
2358
|
-
".cm-ySelectionCaret": {
|
|
2359
|
-
display: "inline-block",
|
|
2360
|
-
insetBlockStart: ".1em",
|
|
2361
|
-
blockSize: "1.4em",
|
|
2362
|
-
verticalAlign: "top"
|
|
2363
|
-
},
|
|
2364
|
-
".cm-yLineSelection": {
|
|
2365
|
-
margin: 0
|
|
2366
|
-
},
|
|
2367
|
-
//
|
|
2368
2335
|
// link
|
|
2369
2336
|
//
|
|
2370
2337
|
".cm-link": {
|
|
@@ -2401,13 +2368,6 @@ var defaultTheme = {
|
|
|
2401
2368
|
textDecoration: "none"
|
|
2402
2369
|
},
|
|
2403
2370
|
//
|
|
2404
|
-
// widgets
|
|
2405
|
-
//
|
|
2406
|
-
".cm-widgetBuffer": {
|
|
2407
|
-
display: "none",
|
|
2408
|
-
height: 0
|
|
2409
|
-
},
|
|
2410
|
-
//
|
|
2411
2371
|
// table
|
|
2412
2372
|
//
|
|
2413
2373
|
".cm-table *": {
|
|
@@ -2438,27 +2398,17 @@ var defaultTheme = {
|
|
|
2438
2398
|
},
|
|
2439
2399
|
//
|
|
2440
2400
|
// font size
|
|
2441
|
-
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
2401
|
+
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
2402
|
+
// but it's far more verbose than it needs to be.
|
|
2442
2403
|
//
|
|
2443
|
-
...Object.keys(
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = {
|
|
2452
|
-
height
|
|
2453
|
-
};
|
|
2454
|
-
acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = {
|
|
2455
|
-
height
|
|
2456
|
-
};
|
|
2457
|
-
acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = {
|
|
2458
|
-
height
|
|
2459
|
-
};
|
|
2460
|
-
return acc;
|
|
2461
|
-
}, {}),
|
|
2404
|
+
// ...Object.keys(get(tokens, 'extend.fontSize', {})).reduce((acc: Record<string, any>, fontSize) => {
|
|
2405
|
+
// const height = get(tokens, ['extend', 'fontSize', fontSize, 1, 'lineHeight']);
|
|
2406
|
+
//
|
|
2407
|
+
// acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = { height };
|
|
2408
|
+
// acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = { height };
|
|
2409
|
+
// acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = { height };
|
|
2410
|
+
// return acc;
|
|
2411
|
+
// }, {}),
|
|
2462
2412
|
/**
|
|
2463
2413
|
* Panels
|
|
2464
2414
|
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
@@ -2509,7 +2459,9 @@ var textTheme = {
|
|
|
2509
2459
|
}
|
|
2510
2460
|
};
|
|
2511
2461
|
var markdownTheme = {
|
|
2512
|
-
|
|
2462
|
+
".cm-scroller": {
|
|
2463
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2464
|
+
},
|
|
2513
2465
|
".cm-placeholder": {
|
|
2514
2466
|
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2515
2467
|
}
|
|
@@ -2528,21 +2480,23 @@ var EditorModes = [
|
|
|
2528
2480
|
"default",
|
|
2529
2481
|
"vim"
|
|
2530
2482
|
];
|
|
2531
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
|
|
2532
|
-
const { themeMode } = useThemeContext();
|
|
2483
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, focus, selection, readonly, comments: comments2, extensions = [], editorMode, theme, slots = defaultSlots }, forwardedRef) => {
|
|
2533
2484
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
2534
2485
|
tabBehavior: "limited"
|
|
2535
2486
|
});
|
|
2536
|
-
const
|
|
2537
|
-
const
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
state,
|
|
2487
|
+
const { themeMode } = useThemeContext();
|
|
2488
|
+
const rootRef = useRef(null);
|
|
2489
|
+
const [view, setView] = useState(null);
|
|
2490
|
+
useImperativeHandle(forwardedRef, () => view, [
|
|
2541
2491
|
view
|
|
2542
|
-
|
|
2492
|
+
]);
|
|
2493
|
+
useEffect(() => {
|
|
2494
|
+
if (view && focus) {
|
|
2495
|
+
view.focus();
|
|
2496
|
+
}
|
|
2497
|
+
}, [
|
|
2543
2498
|
view,
|
|
2544
|
-
|
|
2545
|
-
root
|
|
2499
|
+
focus
|
|
2546
2500
|
]);
|
|
2547
2501
|
const { awareness: awareness2, peer } = model;
|
|
2548
2502
|
useEffect(() => {
|
|
@@ -2566,7 +2520,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2566
2520
|
themeMode
|
|
2567
2521
|
]);
|
|
2568
2522
|
useEffect(() => {
|
|
2569
|
-
if (view && comments2
|
|
2523
|
+
if (view && comments2 !== void 0) {
|
|
2570
2524
|
view.dispatch({
|
|
2571
2525
|
effects: setCommentRange.of({
|
|
2572
2526
|
model,
|
|
@@ -2579,11 +2533,13 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2579
2533
|
comments2
|
|
2580
2534
|
]);
|
|
2581
2535
|
useEffect(() => {
|
|
2582
|
-
if (!
|
|
2536
|
+
if (!model || !rootRef.current) {
|
|
2583
2537
|
return;
|
|
2584
2538
|
}
|
|
2585
|
-
const
|
|
2539
|
+
const state = EditorState2.create({
|
|
2586
2540
|
doc: model.text(),
|
|
2541
|
+
// TODO(burdon): Composer should store and set selection when switching documents.
|
|
2542
|
+
selection,
|
|
2587
2543
|
extensions: [
|
|
2588
2544
|
readonly && EditorState2.readOnly.of(readonly),
|
|
2589
2545
|
// TODO(burdon): Factor out VIM mode? (manage via MarkdownPlugin).
|
|
@@ -2591,7 +2547,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2591
2547
|
// Theme.
|
|
2592
2548
|
// TODO(burdon): Make theme configurable.
|
|
2593
2549
|
EditorView12.baseTheme(defaultTheme),
|
|
2594
|
-
EditorView12.theme(
|
|
2550
|
+
EditorView12.theme(theme ?? {}),
|
|
2595
2551
|
EditorView12.darkTheme.of(themeMode === "dark"),
|
|
2596
2552
|
// Storage and replication.
|
|
2597
2553
|
model.extension,
|
|
@@ -2600,19 +2556,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2600
2556
|
].filter(Boolean)
|
|
2601
2557
|
});
|
|
2602
2558
|
view?.destroy();
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
state: state2,
|
|
2607
|
-
parent: root
|
|
2608
|
-
})
|
|
2559
|
+
const newView = new EditorView12({
|
|
2560
|
+
parent: rootRef.current,
|
|
2561
|
+
state
|
|
2609
2562
|
});
|
|
2563
|
+
setView(newView);
|
|
2610
2564
|
return () => {
|
|
2611
|
-
|
|
2612
|
-
|
|
2565
|
+
newView?.destroy();
|
|
2566
|
+
setView(null);
|
|
2613
2567
|
};
|
|
2614
2568
|
}, [
|
|
2615
|
-
|
|
2569
|
+
rootRef,
|
|
2616
2570
|
model,
|
|
2617
2571
|
readonly,
|
|
2618
2572
|
editorMode,
|
|
@@ -2621,12 +2575,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2621
2575
|
const handleKeyUp = useCallback((event) => {
|
|
2622
2576
|
const { key, altKey, shiftKey, metaKey, ctrlKey } = event;
|
|
2623
2577
|
switch (key) {
|
|
2624
|
-
case "Enter": {
|
|
2625
|
-
view?.contentDOM.focus();
|
|
2626
|
-
break;
|
|
2627
|
-
}
|
|
2628
2578
|
case "Escape": {
|
|
2629
|
-
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) &&
|
|
2579
|
+
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && rootRef.current?.focus();
|
|
2630
2580
|
break;
|
|
2631
2581
|
}
|
|
2632
2582
|
}
|
|
@@ -2636,16 +2586,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2636
2586
|
]);
|
|
2637
2587
|
return /* @__PURE__ */ React.createElement("div", {
|
|
2638
2588
|
key: model.id,
|
|
2639
|
-
|
|
2589
|
+
role: "none",
|
|
2590
|
+
ref: rootRef,
|
|
2640
2591
|
tabIndex: 0,
|
|
2641
|
-
|
|
2642
|
-
...
|
|
2643
|
-
|
|
2592
|
+
onKeyUp: handleKeyUp,
|
|
2593
|
+
...slots.root,
|
|
2594
|
+
...editorMode !== "vim" && tabsterDOMAttribute
|
|
2644
2595
|
});
|
|
2645
2596
|
});
|
|
2646
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [],
|
|
2597
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, extensions = [], theme = textTheme, slots, ...props }, forwardedRef) => {
|
|
2647
2598
|
const { themeMode } = useThemeContext();
|
|
2648
|
-
const
|
|
2599
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
|
|
2649
2600
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2650
2601
|
ref: forwardedRef,
|
|
2651
2602
|
readonly,
|
|
@@ -2653,17 +2604,18 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
|
|
|
2653
2604
|
basicBundle({
|
|
2654
2605
|
readonly,
|
|
2655
2606
|
themeMode,
|
|
2656
|
-
placeholder:
|
|
2607
|
+
placeholder: placeholder3
|
|
2657
2608
|
}),
|
|
2658
2609
|
...extensions
|
|
2659
2610
|
],
|
|
2660
|
-
|
|
2611
|
+
theme,
|
|
2612
|
+
slots: updatedSlots,
|
|
2661
2613
|
...props
|
|
2662
2614
|
});
|
|
2663
2615
|
});
|
|
2664
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [],
|
|
2616
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, extensions = [], theme = markdownTheme, slots, ...props }, forwardedRef) => {
|
|
2665
2617
|
const { themeMode } = useThemeContext();
|
|
2666
|
-
const
|
|
2618
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
|
|
2667
2619
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2668
2620
|
ref: forwardedRef,
|
|
2669
2621
|
readonly,
|
|
@@ -2671,30 +2623,25 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
2671
2623
|
markdownBundle({
|
|
2672
2624
|
readonly,
|
|
2673
2625
|
themeMode,
|
|
2674
|
-
placeholder:
|
|
2626
|
+
placeholder: placeholder3
|
|
2675
2627
|
}),
|
|
2676
2628
|
...extensions
|
|
2677
2629
|
],
|
|
2678
|
-
|
|
2630
|
+
theme,
|
|
2631
|
+
slots: updatedSlots,
|
|
2679
2632
|
...props
|
|
2680
2633
|
});
|
|
2681
2634
|
});
|
|
2682
2635
|
var defaultSlots = {
|
|
2683
2636
|
root: {
|
|
2684
|
-
className: mx3("p-2", inputSurface)
|
|
2637
|
+
className: mx3("p-2 overflow-y-auto", inputSurface)
|
|
2685
2638
|
}
|
|
2686
2639
|
};
|
|
2687
2640
|
var defaultTextSlots = {
|
|
2688
|
-
...defaultSlots
|
|
2689
|
-
editor: {
|
|
2690
|
-
theme: textTheme
|
|
2691
|
-
}
|
|
2641
|
+
...defaultSlots
|
|
2692
2642
|
};
|
|
2693
2643
|
var defaultMarkdownSlots = {
|
|
2694
|
-
...defaultSlots
|
|
2695
|
-
editor: {
|
|
2696
|
-
theme: markdownTheme
|
|
2697
|
-
}
|
|
2644
|
+
...defaultSlots
|
|
2698
2645
|
};
|
|
2699
2646
|
|
|
2700
2647
|
// packages/ui/react-ui-editor/src/hooks/automerge.ts
|
|
@@ -2817,15 +2764,13 @@ import * as decoding from "lib0/decoding";
|
|
|
2817
2764
|
import * as encoding from "lib0/encoding";
|
|
2818
2765
|
import { Observable } from "lib0/observable";
|
|
2819
2766
|
import * as YP from "y-protocols/awareness";
|
|
2820
|
-
import * as Y2 from "yjs";
|
|
2821
2767
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
2822
2768
|
import { log as log4 } from "@dxos/log";
|
|
2823
|
-
import { arrayToString as arrayToString2, stringToArray as stringToArray2 } from "@dxos/util";
|
|
2824
2769
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs.ts";
|
|
2825
2770
|
var createYjsModel = ({ identity, space, text }) => {
|
|
2826
2771
|
invariant4(text?.doc && text?.content, void 0, {
|
|
2827
2772
|
F: __dxlog_file5,
|
|
2828
|
-
L:
|
|
2773
|
+
L: 21,
|
|
2829
2774
|
S: void 0,
|
|
2830
2775
|
A: [
|
|
2831
2776
|
"text?.doc && text?.content",
|
|
@@ -2841,34 +2786,6 @@ var createYjsModel = ({ identity, space, text }) => {
|
|
|
2841
2786
|
id: text.doc.guid,
|
|
2842
2787
|
content: text.content,
|
|
2843
2788
|
text: () => text.content.toString(),
|
|
2844
|
-
// https://github.com/yjs/yjs?tab=readme-ov-file#relative-positions
|
|
2845
|
-
// TODO(dmaretskyi): Refactor as cursor-converter.
|
|
2846
|
-
getCursorFromRange: (range) => {
|
|
2847
|
-
const from = Y2.encodeRelativePosition(Y2.createRelativePositionFromTypeIndex(text.content, range.from));
|
|
2848
|
-
const to = Y2.encodeRelativePosition(Y2.createRelativePositionFromTypeIndex(text.content, range.to, -1));
|
|
2849
|
-
return [
|
|
2850
|
-
arrayToString2(from),
|
|
2851
|
-
arrayToString2(to)
|
|
2852
|
-
].join(":");
|
|
2853
|
-
},
|
|
2854
|
-
getRangeFromCursor: (cursor) => {
|
|
2855
|
-
invariant4(text.doc, void 0, {
|
|
2856
|
-
F: __dxlog_file5,
|
|
2857
|
-
L: 40,
|
|
2858
|
-
S: void 0,
|
|
2859
|
-
A: [
|
|
2860
|
-
"text.doc",
|
|
2861
|
-
""
|
|
2862
|
-
]
|
|
2863
|
-
});
|
|
2864
|
-
const parts = cursor.split(":");
|
|
2865
|
-
const from = Y2.createAbsolutePositionFromRelativePosition(Y2.decodeRelativePosition(stringToArray2(parts[0])), text.doc);
|
|
2866
|
-
const to = Y2.createAbsolutePositionFromRelativePosition(Y2.decodeRelativePosition(stringToArray2(parts[1])), text.doc);
|
|
2867
|
-
return from && to ? {
|
|
2868
|
-
from: from.index,
|
|
2869
|
-
to: to.index
|
|
2870
|
-
} : void 0;
|
|
2871
|
-
},
|
|
2872
2789
|
extension: [
|
|
2873
2790
|
modelState.init(() => model),
|
|
2874
2791
|
yjs(text.content, provider?.awareness)
|
|
@@ -2918,7 +2835,7 @@ var YAwarenessProvider = class extends Observable {
|
|
|
2918
2835
|
origin
|
|
2919
2836
|
}, {
|
|
2920
2837
|
F: __dxlog_file5,
|
|
2921
|
-
L:
|
|
2838
|
+
L: 100,
|
|
2922
2839
|
S: this,
|
|
2923
2840
|
C: (f, a) => f(...a)
|
|
2924
2841
|
});
|
|
@@ -2931,7 +2848,7 @@ var YAwarenessProvider = class extends Observable {
|
|
|
2931
2848
|
_handleSpaceMessage({ payload }) {
|
|
2932
2849
|
log4("space message", payload, {
|
|
2933
2850
|
F: __dxlog_file5,
|
|
2934
|
-
L:
|
|
2851
|
+
L: 109,
|
|
2935
2852
|
S: this,
|
|
2936
2853
|
C: (f, a) => f(...a)
|
|
2937
2854
|
});
|
|
@@ -2981,7 +2898,7 @@ var modelState = StateField5.define({
|
|
|
2981
2898
|
});
|
|
2982
2899
|
var useTextModel = (props) => {
|
|
2983
2900
|
const { identity, space, text } = props;
|
|
2984
|
-
const [model, setModel] = useState2(
|
|
2901
|
+
const [model, setModel] = useState2();
|
|
2985
2902
|
useEffect2(() => setModel(createModel(props)), [
|
|
2986
2903
|
identity,
|
|
2987
2904
|
space,
|
|
@@ -3040,6 +2957,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
|
|
|
3040
2957
|
export {
|
|
3041
2958
|
AwarenessProvider,
|
|
3042
2959
|
BaseTextEditor,
|
|
2960
|
+
Cursor,
|
|
3043
2961
|
Doc,
|
|
3044
2962
|
EditorModes,
|
|
3045
2963
|
MarkdownEditor,
|
|
@@ -3055,11 +2973,13 @@ export {
|
|
|
3055
2973
|
awareness,
|
|
3056
2974
|
basicBundle,
|
|
3057
2975
|
blast,
|
|
2976
|
+
callbackWrapper,
|
|
3058
2977
|
code2 as code,
|
|
3059
2978
|
codeTheme,
|
|
3060
2979
|
comments,
|
|
3061
2980
|
createAutomergeModel,
|
|
3062
2981
|
createYjsModel,
|
|
2982
|
+
cursorConverter,
|
|
3063
2983
|
defaultMarkdownSlots,
|
|
3064
2984
|
defaultOptions,
|
|
3065
2985
|
defaultSlots,
|