@dxos/react-ui-editor 0.3.11-main.162de7b → 0.3.11-main.18bb4b6
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 +225 -366
- 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/automerge/cursor.d.ts +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/code.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +2 -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 +1 -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 +315 -0
- package/src/extensions/automerge/automerge.ts +2 -2
- package/src/extensions/automerge/cursor.ts +2 -1
- package/src/extensions/awareness.ts +25 -32
- package/src/extensions/code.ts +10 -2
- package/src/extensions/comments.ts +20 -115
- 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 +2 -2
- package/src/extensions/tasklist.ts +53 -77
- package/src/extensions/yjs/cursor.ts +2 -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 +1 -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,7 +11,7 @@ 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";
|
|
@@ -274,30 +274,39 @@ var PatchSemaphore = class {
|
|
|
274
274
|
}
|
|
275
275
|
};
|
|
276
276
|
|
|
277
|
-
// packages/ui/react-ui-editor/src/
|
|
277
|
+
// packages/ui/react-ui-editor/src/extensions/cursor.ts
|
|
278
278
|
import { Facet } from "@codemirror/state";
|
|
279
|
-
var
|
|
279
|
+
var defaultCursorConverter = {
|
|
280
280
|
toCursor: (position) => position.toString(),
|
|
281
281
|
fromCursor: (cursor) => parseInt(cursor)
|
|
282
282
|
};
|
|
283
|
-
var
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// packages/ui/react-ui-editor/src/util/util.ts
|
|
288
|
-
import { log } from "@dxos/log";
|
|
289
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/util.ts";
|
|
290
|
-
var callbackWrapper = (fn) => (...args) => {
|
|
291
|
-
try {
|
|
292
|
-
return fn(...args);
|
|
293
|
-
} catch (error) {
|
|
294
|
-
log.catch(error, void 0, {
|
|
295
|
-
F: __dxlog_file,
|
|
296
|
-
L: 16,
|
|
297
|
-
S: void 0,
|
|
298
|
-
C: (f, a) => f(...a)
|
|
283
|
+
var Cursor = class {
|
|
284
|
+
static {
|
|
285
|
+
this.converter = Facet.define({
|
|
286
|
+
combine: (providers) => providers[0] ?? defaultCursorConverter
|
|
299
287
|
});
|
|
300
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
|
+
}
|
|
301
310
|
};
|
|
302
311
|
|
|
303
312
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
|
@@ -356,7 +365,7 @@ var automerge3 = ({ handle, path }) => {
|
|
|
356
365
|
});
|
|
357
366
|
return {
|
|
358
367
|
extension: [
|
|
359
|
-
|
|
368
|
+
Cursor.converter.of(cursorConverter(handle, path)),
|
|
360
369
|
semaphoreFacet.of(semaphore),
|
|
361
370
|
stateField,
|
|
362
371
|
viewPlugin
|
|
@@ -398,7 +407,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
398
407
|
this._ctx = new Context();
|
|
399
408
|
this._lastAnchor = void 0;
|
|
400
409
|
this._lastHead = void 0;
|
|
401
|
-
this._cursorConverter = view.state.facet(
|
|
410
|
+
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
402
411
|
this._provider = view.state.facet(AwarenessProvider);
|
|
403
412
|
this._provider.open();
|
|
404
413
|
this._provider.remoteStateChange.on(this._ctx, () => {
|
|
@@ -453,7 +462,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
453
462
|
attributes: {
|
|
454
463
|
style: `background-color: ${lightColor}`
|
|
455
464
|
},
|
|
456
|
-
class: "cm-
|
|
465
|
+
class: "cm-collab-selection"
|
|
457
466
|
})
|
|
458
467
|
});
|
|
459
468
|
} else {
|
|
@@ -464,7 +473,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
464
473
|
attributes: {
|
|
465
474
|
style: `background-color: ${color}`
|
|
466
475
|
},
|
|
467
|
-
class: "cm-
|
|
476
|
+
class: "cm-collab-selection"
|
|
468
477
|
})
|
|
469
478
|
});
|
|
470
479
|
decorations.push({
|
|
@@ -474,7 +483,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
474
483
|
attributes: {
|
|
475
484
|
style: `background-color: ${color}`
|
|
476
485
|
},
|
|
477
|
-
class: "cm-
|
|
486
|
+
class: "cm-collab-selection"
|
|
478
487
|
})
|
|
479
488
|
});
|
|
480
489
|
for (let i = startLine.number + 1; i < endLine.number; i++) {
|
|
@@ -485,7 +494,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
485
494
|
value: Decoration.line({
|
|
486
495
|
attributes: {
|
|
487
496
|
style: `background-color: ${color}`,
|
|
488
|
-
class: "cm-
|
|
497
|
+
class: "cm-collab-selectionLine"
|
|
489
498
|
}
|
|
490
499
|
})
|
|
491
500
|
});
|
|
@@ -505,23 +514,21 @@ var RemoteSelectionsDecorator = class {
|
|
|
505
514
|
}
|
|
506
515
|
};
|
|
507
516
|
var RemoteCaretWidget = class extends WidgetType {
|
|
508
|
-
constructor(
|
|
517
|
+
constructor(_name, _color) {
|
|
509
518
|
super();
|
|
510
|
-
this.
|
|
511
|
-
this.
|
|
512
|
-
this.name = name;
|
|
513
|
-
this.color = color;
|
|
519
|
+
this._name = _name;
|
|
520
|
+
this._color = _color;
|
|
514
521
|
}
|
|
515
522
|
toDOM() {
|
|
516
523
|
const span = document.createElement("span");
|
|
517
|
-
span.className = "cm-
|
|
518
|
-
span.style.backgroundColor = this.
|
|
519
|
-
span.style.borderColor = this.
|
|
524
|
+
span.className = "cm-collab-selectionCaret";
|
|
525
|
+
span.style.backgroundColor = this._color;
|
|
526
|
+
span.style.borderColor = this._color;
|
|
520
527
|
const dot = document.createElement("div");
|
|
521
|
-
dot.className = "cm-
|
|
528
|
+
dot.className = "cm-collab-selectionCaretDot";
|
|
522
529
|
const info = document.createElement("div");
|
|
523
|
-
info.className = "cm-
|
|
524
|
-
info.innerText = this.
|
|
530
|
+
info.className = "cm-collab-selectionInfo";
|
|
531
|
+
info.innerText = this._name;
|
|
525
532
|
span.appendChild(document.createTextNode("\u2060"));
|
|
526
533
|
span.appendChild(dot);
|
|
527
534
|
span.appendChild(document.createTextNode("\u2060"));
|
|
@@ -529,15 +536,12 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
|
529
536
|
span.appendChild(document.createTextNode("\u2060"));
|
|
530
537
|
return span;
|
|
531
538
|
}
|
|
532
|
-
eq(widget) {
|
|
533
|
-
return widget.color === this.color;
|
|
534
|
-
}
|
|
535
|
-
compare(widget) {
|
|
536
|
-
return widget.color === this.color;
|
|
537
|
-
}
|
|
538
539
|
updateDOM() {
|
|
539
540
|
return false;
|
|
540
541
|
}
|
|
542
|
+
eq(widget) {
|
|
543
|
+
return widget._color === this._color;
|
|
544
|
+
}
|
|
541
545
|
get estimatedHeight() {
|
|
542
546
|
return -1;
|
|
543
547
|
}
|
|
@@ -546,12 +550,12 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
|
546
550
|
}
|
|
547
551
|
};
|
|
548
552
|
var styles = EditorView.baseTheme({
|
|
549
|
-
".cm-
|
|
550
|
-
".cm-
|
|
553
|
+
".cm-collab-selection": {},
|
|
554
|
+
".cm-collab-selectionLine": {
|
|
551
555
|
padding: 0,
|
|
552
556
|
margin: "0px 2px 0px 4px"
|
|
553
557
|
},
|
|
554
|
-
".cm-
|
|
558
|
+
".cm-collab-selectionCaret": {
|
|
555
559
|
position: "relative",
|
|
556
560
|
borderLeft: "1px solid black",
|
|
557
561
|
borderRight: "1px solid black",
|
|
@@ -560,7 +564,7 @@ var styles = EditorView.baseTheme({
|
|
|
560
564
|
boxSizing: "border-box",
|
|
561
565
|
display: "inline"
|
|
562
566
|
},
|
|
563
|
-
".cm-
|
|
567
|
+
".cm-collab-selectionCaretDot": {
|
|
564
568
|
borderRadius: "50%",
|
|
565
569
|
position: "absolute",
|
|
566
570
|
width: ".4em",
|
|
@@ -571,11 +575,11 @@ var styles = EditorView.baseTheme({
|
|
|
571
575
|
transition: "transform .3s ease-in-out",
|
|
572
576
|
boxSizing: "border-box"
|
|
573
577
|
},
|
|
574
|
-
".cm-
|
|
578
|
+
".cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot": {
|
|
575
579
|
transformOrigin: "bottom center",
|
|
576
580
|
transform: "scale(0)"
|
|
577
581
|
},
|
|
578
|
-
".cm-
|
|
582
|
+
".cm-collab-selectionInfo": {
|
|
579
583
|
position: "absolute",
|
|
580
584
|
top: "-1.05em",
|
|
581
585
|
left: "-1px",
|
|
@@ -596,7 +600,7 @@ var styles = EditorView.baseTheme({
|
|
|
596
600
|
transitionDelay: "0s",
|
|
597
601
|
whiteSpace: "nowrap"
|
|
598
602
|
},
|
|
599
|
-
".cm-
|
|
603
|
+
".cm-collab-selectionCaret:hover > .cm-collab-selectionInfo": {
|
|
600
604
|
opacity: 1,
|
|
601
605
|
transitionDelay: "0s"
|
|
602
606
|
}
|
|
@@ -623,7 +627,7 @@ var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
|
|
|
623
627
|
import { EditorView as EditorView3, keymap as keymap2 } from "@codemirror/view";
|
|
624
628
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
625
629
|
import { invariant } from "@dxos/invariant";
|
|
626
|
-
var
|
|
630
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
|
627
631
|
var defaultOptions = {
|
|
628
632
|
effect: 2,
|
|
629
633
|
maxParticles: 200,
|
|
@@ -750,7 +754,7 @@ var Blaster = class {
|
|
|
750
754
|
}
|
|
751
755
|
initialize() {
|
|
752
756
|
invariant(!this._canvas && !this._ctx, void 0, {
|
|
753
|
-
F:
|
|
757
|
+
F: __dxlog_file,
|
|
754
758
|
L: 138,
|
|
755
759
|
S: this,
|
|
756
760
|
A: [
|
|
@@ -787,7 +791,7 @@ var Blaster = class {
|
|
|
787
791
|
}
|
|
788
792
|
start() {
|
|
789
793
|
invariant(this._canvas && this._ctx, void 0, {
|
|
790
|
-
F:
|
|
794
|
+
F: __dxlog_file,
|
|
791
795
|
L: 177,
|
|
792
796
|
S: this,
|
|
793
797
|
A: [
|
|
@@ -1057,7 +1061,7 @@ var getLineRange = (lines, from, to) => {
|
|
|
1057
1061
|
var code2 = () => {
|
|
1058
1062
|
const getDecorations = (view) => {
|
|
1059
1063
|
const decorations = [];
|
|
1060
|
-
if (view.state.readOnly) {
|
|
1064
|
+
if (!view.hasFocus || view.state.readOnly) {
|
|
1061
1065
|
const text = view.state.doc.sliceString(0);
|
|
1062
1066
|
const matches = text.matchAll(CODE_REGEX);
|
|
1063
1067
|
const blocks = view.viewportLineBlocks;
|
|
@@ -1076,10 +1080,15 @@ var code2 = () => {
|
|
|
1076
1080
|
return [
|
|
1077
1081
|
ViewPlugin3.fromClass(class {
|
|
1078
1082
|
constructor(view) {
|
|
1083
|
+
this.hasFocus = false;
|
|
1079
1084
|
this.decorations = getDecorations(view);
|
|
1080
1085
|
}
|
|
1081
1086
|
update(update2) {
|
|
1082
|
-
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;
|
|
1083
1092
|
this.decorations = getDecorations(update2.view);
|
|
1084
1093
|
}
|
|
1085
1094
|
}
|
|
@@ -1092,23 +1101,32 @@ var code2 = () => {
|
|
|
1092
1101
|
|
|
1093
1102
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1094
1103
|
import { StateEffect as StateEffect2, StateField as StateField2 } from "@codemirror/state";
|
|
1095
|
-
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";
|
|
1096
1105
|
import sortBy from "lodash.sortby";
|
|
1097
1106
|
import { debounce } from "@dxos/async";
|
|
1098
1107
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1099
1108
|
import { log as log2 } from "@dxos/log";
|
|
1100
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
|
|
1101
1128
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
|
|
1102
1129
|
var styles3 = EditorView5.baseTheme({
|
|
1103
|
-
"& .cm-bookmark": {
|
|
1104
|
-
cursor: "pointer",
|
|
1105
|
-
margin: "4px",
|
|
1106
|
-
padding: "4px",
|
|
1107
|
-
backgroundColor: "yellow"
|
|
1108
|
-
},
|
|
1109
|
-
"& .cm-bookmark-selected": {
|
|
1110
|
-
backgroundColor: "orange"
|
|
1111
|
-
},
|
|
1112
1130
|
"& .cm-comment": {
|
|
1113
1131
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
1114
1132
|
},
|
|
@@ -1147,7 +1165,7 @@ var commentsStateField = StateField2.define({
|
|
|
1147
1165
|
ranges: []
|
|
1148
1166
|
}),
|
|
1149
1167
|
update: (value, tr) => {
|
|
1150
|
-
const cursorConverter3 = tr.state.facet(
|
|
1168
|
+
const cursorConverter3 = tr.state.facet(Cursor.converter);
|
|
1151
1169
|
for (const effect of tr.effects) {
|
|
1152
1170
|
if (effect.is(setSelection)) {
|
|
1153
1171
|
return {
|
|
@@ -1158,7 +1176,7 @@ var commentsStateField = StateField2.define({
|
|
|
1158
1176
|
if (effect.is(setCommentRange)) {
|
|
1159
1177
|
const { comments: comments2 } = effect.value;
|
|
1160
1178
|
const ranges = comments2.map((comment) => {
|
|
1161
|
-
const range = getRangeFromCursor(cursorConverter3, comment.cursor);
|
|
1179
|
+
const range = Cursor.getRangeFromCursor(cursorConverter3, comment.cursor);
|
|
1162
1180
|
return range && {
|
|
1163
1181
|
...comment,
|
|
1164
1182
|
...range
|
|
@@ -1196,42 +1214,14 @@ var highlightDecorations = EditorView5.decorations.compute([
|
|
|
1196
1214
|
}).filter(nonNullable) ?? [];
|
|
1197
1215
|
return Decoration3.set(decorations);
|
|
1198
1216
|
});
|
|
1199
|
-
var BookmarkWidget = class extends WidgetType2 {
|
|
1200
|
-
constructor(_anchor, _id, _handleClick) {
|
|
1201
|
-
super();
|
|
1202
|
-
this._anchor = _anchor;
|
|
1203
|
-
this._id = _id;
|
|
1204
|
-
this._handleClick = _handleClick;
|
|
1205
|
-
invariant2(this._id, void 0, {
|
|
1206
|
-
F: __dxlog_file3,
|
|
1207
|
-
L: 168,
|
|
1208
|
-
S: this,
|
|
1209
|
-
A: [
|
|
1210
|
-
"this._id",
|
|
1211
|
-
""
|
|
1212
|
-
]
|
|
1213
|
-
});
|
|
1214
|
-
}
|
|
1215
|
-
eq(other) {
|
|
1216
|
-
return this._anchor === other._anchor && this._id === other._id;
|
|
1217
|
-
}
|
|
1218
|
-
toDOM() {
|
|
1219
|
-
const span = document.createElement("span");
|
|
1220
|
-
span.className = "cm-bookmark";
|
|
1221
|
-
span.textContent = "\u203B";
|
|
1222
|
-
if (this._handleClick) {
|
|
1223
|
-
span.onclick = () => this._handleClick();
|
|
1224
|
-
}
|
|
1225
|
-
return span;
|
|
1226
|
-
}
|
|
1227
|
-
};
|
|
1228
1217
|
var comments = (options = {}) => {
|
|
1218
|
+
const { key: shortcut = "meta-'" } = options;
|
|
1229
1219
|
const handleSelect = debounce((state) => options.onSelect?.(state), 200);
|
|
1230
1220
|
const createCommentThread = (view) => {
|
|
1231
|
-
const cursorConverter3 = view.state.facet(
|
|
1221
|
+
const cursorConverter3 = view.state.facet(Cursor.converter);
|
|
1232
1222
|
invariant2(options.onCreate, void 0, {
|
|
1233
1223
|
F: __dxlog_file3,
|
|
1234
|
-
L:
|
|
1224
|
+
L: 177,
|
|
1235
1225
|
S: void 0,
|
|
1236
1226
|
A: [
|
|
1237
1227
|
"options.onCreate",
|
|
@@ -1242,12 +1232,12 @@ var comments = (options = {}) => {
|
|
|
1242
1232
|
if (from === to) {
|
|
1243
1233
|
return false;
|
|
1244
1234
|
}
|
|
1245
|
-
const
|
|
1235
|
+
const cursor = Cursor.getCursorFromRange(cursorConverter3, {
|
|
1246
1236
|
from,
|
|
1247
1237
|
to
|
|
1248
1238
|
});
|
|
1249
|
-
if (
|
|
1250
|
-
const id = callbackWrapper(options.onCreate)(
|
|
1239
|
+
if (cursor) {
|
|
1240
|
+
const id = callbackWrapper(options.onCreate)(cursor, view.coordsAtPos(from));
|
|
1251
1241
|
if (id) {
|
|
1252
1242
|
view.dispatch({
|
|
1253
1243
|
effects: setSelection.of({
|
|
@@ -1274,35 +1264,7 @@ var comments = (options = {}) => {
|
|
|
1274
1264
|
}
|
|
1275
1265
|
return false;
|
|
1276
1266
|
};
|
|
1277
|
-
const bookmarksViewPlugin = ViewPlugin4.fromClass(class BookmarkViewPlugin {
|
|
1278
|
-
static {
|
|
1279
|
-
// Match markdown footnotes (option).
|
|
1280
|
-
// https://www.markdownguide.org/extended-syntax/#footnotes
|
|
1281
|
-
this.bookmarkMatcher = new MatchDecorator({
|
|
1282
|
-
regexp: /\[\^(\w+)\]/g,
|
|
1283
|
-
decoration: (match, view, pos) => {
|
|
1284
|
-
const id = match[1];
|
|
1285
|
-
return Decoration3.replace({
|
|
1286
|
-
id,
|
|
1287
|
-
widget: new BookmarkWidget(pos, id)
|
|
1288
|
-
});
|
|
1289
|
-
}
|
|
1290
|
-
});
|
|
1291
|
-
}
|
|
1292
|
-
constructor(view) {
|
|
1293
|
-
this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.createDeco(view);
|
|
1294
|
-
}
|
|
1295
|
-
update(update2) {
|
|
1296
|
-
this.bookmarks = BookmarkViewPlugin.bookmarkMatcher.updateDeco(update2, this.bookmarks);
|
|
1297
|
-
}
|
|
1298
|
-
}, {
|
|
1299
|
-
decorations: (instance) => instance.bookmarks,
|
|
1300
|
-
provide: (plugin) => EditorView5.atomicRanges.of((view) => {
|
|
1301
|
-
return view.plugin(plugin)?.bookmarks || Decoration3.none;
|
|
1302
|
-
})
|
|
1303
|
-
});
|
|
1304
1267
|
return [
|
|
1305
|
-
bookmarksViewPlugin,
|
|
1306
1268
|
commentsStateField,
|
|
1307
1269
|
highlightDecorations,
|
|
1308
1270
|
styles3,
|
|
@@ -1311,7 +1273,7 @@ var comments = (options = {}) => {
|
|
|
1311
1273
|
//
|
|
1312
1274
|
options.onCreate ? keymap3.of([
|
|
1313
1275
|
{
|
|
1314
|
-
key:
|
|
1276
|
+
key: shortcut,
|
|
1315
1277
|
run: callbackWrapper(createCommentThread)
|
|
1316
1278
|
}
|
|
1317
1279
|
]) : [],
|
|
@@ -1328,7 +1290,7 @@ var comments = (options = {}) => {
|
|
|
1328
1290
|
above: true,
|
|
1329
1291
|
create: () => {
|
|
1330
1292
|
const el = document.createElement("div");
|
|
1331
|
-
options.onHover?.(el);
|
|
1293
|
+
options.onHover?.(el, shortcut);
|
|
1332
1294
|
return {
|
|
1333
1295
|
dom: el,
|
|
1334
1296
|
offset: {
|
|
@@ -1349,27 +1311,27 @@ var comments = (options = {}) => {
|
|
|
1349
1311
|
// TODO(burdon): Is there a better (finer grained) way to do this?
|
|
1350
1312
|
//
|
|
1351
1313
|
EditorView5.updateListener.of(({ view, state, changes }) => {
|
|
1352
|
-
const cursorConverter3 = view.state.facet(
|
|
1314
|
+
const cursorConverter3 = view.state.facet(Cursor.converter);
|
|
1353
1315
|
{
|
|
1354
1316
|
let mod = false;
|
|
1355
1317
|
const { active, ranges } = state.field(commentsStateField);
|
|
1356
1318
|
changes.iterChanges((from, to, from2, to2) => {
|
|
1357
1319
|
ranges.forEach((range) => {
|
|
1358
1320
|
if (from2 === to2) {
|
|
1359
|
-
const newRange = getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1321
|
+
const newRange = Cursor.getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1360
1322
|
if (!newRange || newRange.to - newRange.from === 0) {
|
|
1361
1323
|
log2.info("deleted comment", {
|
|
1362
1324
|
thread: range.id
|
|
1363
1325
|
}, {
|
|
1364
1326
|
F: __dxlog_file3,
|
|
1365
|
-
L:
|
|
1327
|
+
L: 274,
|
|
1366
1328
|
S: void 0,
|
|
1367
1329
|
C: (f, a) => f(...a)
|
|
1368
1330
|
});
|
|
1369
1331
|
}
|
|
1370
1332
|
}
|
|
1371
1333
|
if (from <= range.to) {
|
|
1372
|
-
const newRange = getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1334
|
+
const newRange = Cursor.getRangeFromCursor(cursorConverter3, range.cursor);
|
|
1373
1335
|
Object.assign(range, newRange);
|
|
1374
1336
|
mod = true;
|
|
1375
1337
|
}
|
|
@@ -1418,26 +1380,9 @@ var comments = (options = {}) => {
|
|
|
1418
1380
|
})
|
|
1419
1381
|
];
|
|
1420
1382
|
};
|
|
1421
|
-
var getCursorFromRange = (cursorConverter3, range) => {
|
|
1422
|
-
const from = cursorConverter3.toCursor(range.from);
|
|
1423
|
-
const to = cursorConverter3.toCursor(range.to, -1);
|
|
1424
|
-
return [
|
|
1425
|
-
from,
|
|
1426
|
-
to
|
|
1427
|
-
].join(":");
|
|
1428
|
-
};
|
|
1429
|
-
var getRangeFromCursor = (cursorConverter3, cursor) => {
|
|
1430
|
-
const parts = cursor.split(":");
|
|
1431
|
-
const from = cursorConverter3.fromCursor(parts[0]);
|
|
1432
|
-
const to = cursorConverter3.fromCursor(parts[1]);
|
|
1433
|
-
return from !== void 0 && to !== void 0 ? {
|
|
1434
|
-
from,
|
|
1435
|
-
to
|
|
1436
|
-
} : void 0;
|
|
1437
|
-
};
|
|
1438
1383
|
|
|
1439
1384
|
// packages/ui/react-ui-editor/src/extensions/hr.ts
|
|
1440
|
-
import { Decoration as Decoration4, EditorView as EditorView6, MatchDecorator
|
|
1385
|
+
import { Decoration as Decoration4, EditorView as EditorView6, MatchDecorator, ViewPlugin as ViewPlugin4, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1441
1386
|
var styles4 = EditorView6.baseTheme({
|
|
1442
1387
|
"& .cm-hr": {
|
|
1443
1388
|
// TODO(burdon): ???
|
|
@@ -1445,7 +1390,7 @@ var styles4 = EditorView6.baseTheme({
|
|
|
1445
1390
|
borderBottom: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
1446
1391
|
}
|
|
1447
1392
|
});
|
|
1448
|
-
var HorizontalRuleWidget = class extends
|
|
1393
|
+
var HorizontalRuleWidget = class extends WidgetType2 {
|
|
1449
1394
|
constructor(_pos) {
|
|
1450
1395
|
super();
|
|
1451
1396
|
this._pos = _pos;
|
|
@@ -1459,7 +1404,7 @@ var HorizontalRuleWidget = class extends WidgetType3 {
|
|
|
1459
1404
|
return el;
|
|
1460
1405
|
}
|
|
1461
1406
|
};
|
|
1462
|
-
var placeholderMatcher = new
|
|
1407
|
+
var placeholderMatcher = new MatchDecorator({
|
|
1463
1408
|
regexp: /^---$/g,
|
|
1464
1409
|
decoration: (match, view, pos) => Decoration4.replace({
|
|
1465
1410
|
widget: new HorizontalRuleWidget(pos)
|
|
@@ -1467,7 +1412,7 @@ var placeholderMatcher = new MatchDecorator2({
|
|
|
1467
1412
|
});
|
|
1468
1413
|
var hr = () => [
|
|
1469
1414
|
styles4,
|
|
1470
|
-
|
|
1415
|
+
ViewPlugin4.fromClass(class {
|
|
1471
1416
|
constructor(view) {
|
|
1472
1417
|
this.rules = placeholderMatcher.createDeco(view);
|
|
1473
1418
|
}
|
|
@@ -1486,7 +1431,7 @@ var hr = () => [
|
|
|
1486
1431
|
// packages/ui/react-ui-editor/src/extensions/image.ts
|
|
1487
1432
|
import { syntaxTree } from "@codemirror/language";
|
|
1488
1433
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
1489
|
-
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as
|
|
1434
|
+
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
1490
1435
|
var image = (options = {}) => {
|
|
1491
1436
|
return StateField3.define({
|
|
1492
1437
|
create: (state) => {
|
|
@@ -1538,7 +1483,7 @@ var buildDecorations = (from, to, state) => {
|
|
|
1538
1483
|
});
|
|
1539
1484
|
return decorations;
|
|
1540
1485
|
};
|
|
1541
|
-
var ImageWidget = class extends
|
|
1486
|
+
var ImageWidget = class extends WidgetType3 {
|
|
1542
1487
|
constructor(_url) {
|
|
1543
1488
|
super();
|
|
1544
1489
|
this._url = _url;
|
|
@@ -1558,11 +1503,11 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
1558
1503
|
// packages/ui/react-ui-editor/src/extensions/link.ts
|
|
1559
1504
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1560
1505
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
1561
|
-
import { Decoration as Decoration6, WidgetType as
|
|
1506
|
+
import { Decoration as Decoration6, WidgetType as WidgetType4, hoverTooltip as hoverTooltip2, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
1562
1507
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
1563
1508
|
var link = (options = {}) => {
|
|
1564
1509
|
const extensions = [
|
|
1565
|
-
|
|
1510
|
+
ViewPlugin5.fromClass(class {
|
|
1566
1511
|
constructor(view) {
|
|
1567
1512
|
this.decorations = buildDecorations2(view, options);
|
|
1568
1513
|
}
|
|
@@ -1613,7 +1558,7 @@ var link = (options = {}) => {
|
|
|
1613
1558
|
}
|
|
1614
1559
|
return extensions;
|
|
1615
1560
|
};
|
|
1616
|
-
var LinkButton = class extends
|
|
1561
|
+
var LinkButton = class extends WidgetType4 {
|
|
1617
1562
|
constructor(_url, _onAttach) {
|
|
1618
1563
|
super();
|
|
1619
1564
|
this._url = _url;
|
|
@@ -1628,7 +1573,7 @@ var LinkButton = class extends WidgetType5 {
|
|
|
1628
1573
|
return el;
|
|
1629
1574
|
}
|
|
1630
1575
|
};
|
|
1631
|
-
var LinkText = class extends
|
|
1576
|
+
var LinkText = class extends WidgetType4 {
|
|
1632
1577
|
constructor(_text, _url) {
|
|
1633
1578
|
super();
|
|
1634
1579
|
this._text = _text;
|
|
@@ -1728,7 +1673,6 @@ var markdownTags = {
|
|
|
1728
1673
|
CodeText: Tag.define(),
|
|
1729
1674
|
EmphasisMark: Tag.define(),
|
|
1730
1675
|
HeaderMark: Tag.define(),
|
|
1731
|
-
// HorizontalRule: Tag.define(),
|
|
1732
1676
|
InlineCode: Tag.define(),
|
|
1733
1677
|
LinkLabel: Tag.define(),
|
|
1734
1678
|
LinkReference: Tag.define(),
|
|
@@ -1892,12 +1836,6 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
1892
1836
|
],
|
|
1893
1837
|
class: blockquote
|
|
1894
1838
|
},
|
|
1895
|
-
// TODO(burdon): Replace with extension.
|
|
1896
|
-
// {
|
|
1897
|
-
// tag: [markdownTags.HorizontalRule],
|
|
1898
|
-
// class: mx(horizontalRule, readonly && '-indent-[100rem]'),
|
|
1899
|
-
// },
|
|
1900
|
-
// TODO(burdon): Only if being edited.
|
|
1901
1839
|
{
|
|
1902
1840
|
tag: [
|
|
1903
1841
|
markdownTags.TableCell
|
|
@@ -1991,7 +1929,7 @@ var mention = ({ onSearch }) => {
|
|
|
1991
1929
|
// packages/ui/react-ui-editor/src/extensions/table.ts
|
|
1992
1930
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1993
1931
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField4 } from "@codemirror/state";
|
|
1994
|
-
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as
|
|
1932
|
+
import { Decoration as Decoration7, EditorView as EditorView10, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
1995
1933
|
var table = (options = {}) => {
|
|
1996
1934
|
return StateField4.define({
|
|
1997
1935
|
create: (state) => update(state, options),
|
|
@@ -2049,7 +1987,7 @@ var update = (state, options) => {
|
|
|
2049
1987
|
});
|
|
2050
1988
|
return builder.finish();
|
|
2051
1989
|
};
|
|
2052
|
-
var TableWidget = class extends
|
|
1990
|
+
var TableWidget = class extends WidgetType5 {
|
|
2053
1991
|
constructor(_table) {
|
|
2054
1992
|
super();
|
|
2055
1993
|
this._table = _table;
|
|
@@ -2087,87 +2025,85 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2087
2025
|
};
|
|
2088
2026
|
|
|
2089
2027
|
// packages/ui/react-ui-editor/src/extensions/tasklist.ts
|
|
2090
|
-
import {
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
}
|
|
2096
|
-
});
|
|
2097
|
-
var CheckboxWidget = class extends WidgetType7 {
|
|
2098
|
-
constructor(_checked, _indent, _onCheck) {
|
|
2028
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
2029
|
+
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
2030
|
+
import { EditorView as EditorView11, Decoration as Decoration8, WidgetType as WidgetType6, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
2031
|
+
var CheckboxWidget = class extends WidgetType6 {
|
|
2032
|
+
constructor(_checked) {
|
|
2099
2033
|
super();
|
|
2100
2034
|
this._checked = _checked;
|
|
2101
|
-
this._indent = _indent;
|
|
2102
|
-
this._onCheck = _onCheck;
|
|
2103
2035
|
}
|
|
2104
2036
|
eq(other) {
|
|
2105
|
-
return this._checked === other._checked
|
|
2037
|
+
return this._checked === other._checked;
|
|
2106
2038
|
}
|
|
2107
2039
|
toDOM(view) {
|
|
2108
|
-
const
|
|
2109
|
-
wrap.className = "cm-task-item";
|
|
2110
|
-
wrap.setAttribute("aria-hidden", "true");
|
|
2111
|
-
wrap.style.setProperty("margin-left", this._indent * 24 + "px");
|
|
2112
|
-
const input = wrap.appendChild(document.createElement("input"));
|
|
2040
|
+
const input = document.createElement("input");
|
|
2113
2041
|
input.type = "checkbox";
|
|
2114
2042
|
input.checked = this._checked;
|
|
2115
|
-
if (
|
|
2043
|
+
if (view.state.readOnly) {
|
|
2116
2044
|
input.setAttribute("disabled", "true");
|
|
2117
|
-
}
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2045
|
+
} else {
|
|
2046
|
+
input.onmousedown = (event) => {
|
|
2047
|
+
const pos = view.posAtDOM(input);
|
|
2048
|
+
const text = view.state.sliceDoc(pos, pos + 3);
|
|
2049
|
+
if (text === (this._checked ? "[x]" : "[ ]")) {
|
|
2050
|
+
view.dispatch({
|
|
2051
|
+
changes: {
|
|
2052
|
+
from: pos + 1,
|
|
2053
|
+
to: pos + 2,
|
|
2054
|
+
insert: this._checked ? " " : "x"
|
|
2055
|
+
}
|
|
2056
|
+
});
|
|
2057
|
+
event.preventDefault();
|
|
2058
|
+
}
|
|
2122
2059
|
};
|
|
2123
2060
|
}
|
|
2124
|
-
return
|
|
2061
|
+
return input;
|
|
2125
2062
|
}
|
|
2126
2063
|
ignoreEvent() {
|
|
2127
2064
|
return false;
|
|
2128
2065
|
}
|
|
2129
2066
|
};
|
|
2067
|
+
var checkedDeco = Decoration8.replace({
|
|
2068
|
+
widget: new CheckboxWidget(true)
|
|
2069
|
+
});
|
|
2070
|
+
var uncheckedDeco = Decoration8.replace({
|
|
2071
|
+
widget: new CheckboxWidget(false)
|
|
2072
|
+
});
|
|
2130
2073
|
var tasklist = (options = {}) => {
|
|
2131
|
-
|
|
2132
|
-
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
2133
|
-
decoration: (match, view, pos) => {
|
|
2134
|
-
const indent = Math.floor(match[1].length / 2);
|
|
2135
|
-
const checked = match[2] === "x" || match[2] === "X";
|
|
2136
|
-
return Decoration8.replace({
|
|
2137
|
-
widget: new CheckboxWidget(checked, indent, view.state.readOnly ? void 0 : (checked2) => {
|
|
2138
|
-
const idx = pos + match[0].indexOf("[") + 1;
|
|
2139
|
-
view.dispatch({
|
|
2140
|
-
changes: {
|
|
2141
|
-
from: idx,
|
|
2142
|
-
to: idx + 1,
|
|
2143
|
-
insert: checked2 ? "x" : " "
|
|
2144
|
-
},
|
|
2145
|
-
// TODO(burdon): Restore cursor position? More useful to move to end of line (can indent).
|
|
2146
|
-
selection: {
|
|
2147
|
-
anchor: idx + 3
|
|
2148
|
-
}
|
|
2149
|
-
});
|
|
2150
|
-
})
|
|
2151
|
-
});
|
|
2152
|
-
}
|
|
2153
|
-
});
|
|
2154
|
-
const tasks = ViewPlugin7.fromClass(class {
|
|
2074
|
+
return ViewPlugin6.fromClass(class {
|
|
2155
2075
|
constructor(view) {
|
|
2156
|
-
this.
|
|
2076
|
+
this.decorations = buildDecorations3(view);
|
|
2157
2077
|
}
|
|
2158
2078
|
update(update2) {
|
|
2159
|
-
|
|
2079
|
+
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
2080
|
+
this.decorations = buildDecorations3(update2.view);
|
|
2081
|
+
}
|
|
2160
2082
|
}
|
|
2161
2083
|
}, {
|
|
2162
|
-
decorations: (
|
|
2084
|
+
decorations: (v) => v.decorations,
|
|
2163
2085
|
provide: (plugin) => EditorView11.atomicRanges.of((view) => {
|
|
2164
|
-
return view.plugin(plugin)?.
|
|
2086
|
+
return view.plugin(plugin)?.decorations || Decoration8.none;
|
|
2165
2087
|
})
|
|
2166
2088
|
});
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2089
|
+
};
|
|
2090
|
+
var buildDecorations3 = (view) => {
|
|
2091
|
+
const builder = new RangeSetBuilder3();
|
|
2092
|
+
const { state } = view;
|
|
2093
|
+
const cursor = state.selection.main.head;
|
|
2094
|
+
for (const { from, to } of view.visibleRanges) {
|
|
2095
|
+
syntaxTree4(state).iterate({
|
|
2096
|
+
enter: (node) => {
|
|
2097
|
+
if (node.name === "TaskMarker" && (cursor < node.from || cursor > node.to)) {
|
|
2098
|
+
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2099
|
+
builder.add(node.from, node.to, checked ? checkedDeco : uncheckedDeco);
|
|
2100
|
+
}
|
|
2101
|
+
},
|
|
2102
|
+
from,
|
|
2103
|
+
to
|
|
2104
|
+
});
|
|
2105
|
+
}
|
|
2106
|
+
return builder.finish();
|
|
2171
2107
|
};
|
|
2172
2108
|
|
|
2173
2109
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
@@ -2244,7 +2180,7 @@ var cursorConverter2 = (text) => ({
|
|
|
2244
2180
|
|
|
2245
2181
|
// packages/ui/react-ui-editor/src/extensions/yjs/yjs.ts
|
|
2246
2182
|
var yjs = (content, awareness2) => [
|
|
2247
|
-
|
|
2183
|
+
Cursor.converter.of(cursorConverter2(content)),
|
|
2248
2184
|
yCollab(content, awareness2)
|
|
2249
2185
|
];
|
|
2250
2186
|
|
|
@@ -2341,33 +2277,6 @@ var defaultTheme = {
|
|
|
2341
2277
|
backgroundColor: get3(tokens, "extend.colors.yellow.700")
|
|
2342
2278
|
},
|
|
2343
2279
|
//
|
|
2344
|
-
// collaboration
|
|
2345
|
-
// TODO(burdon): Review classnames (YJS dependent?) Note: e2e tests depend on this class.
|
|
2346
|
-
//
|
|
2347
|
-
"&light .cm-ySelection, &light .cm-yLineSelection": {
|
|
2348
|
-
mixBlendMode: "multiply"
|
|
2349
|
-
},
|
|
2350
|
-
"&dark .cm-ySelection, &dark .cm-yLineSelection": {
|
|
2351
|
-
mixBlendMode: "screen"
|
|
2352
|
-
},
|
|
2353
|
-
".cm-ySelectionInfo": {
|
|
2354
|
-
padding: "2px 4px",
|
|
2355
|
-
marginBlockStart: "-4px"
|
|
2356
|
-
},
|
|
2357
|
-
".cm-ySelection, & .cm-selectionMatch": {
|
|
2358
|
-
paddingBlockStart: ".15em",
|
|
2359
|
-
paddingBlockEnd: ".15em"
|
|
2360
|
-
},
|
|
2361
|
-
".cm-ySelectionCaret": {
|
|
2362
|
-
display: "inline-block",
|
|
2363
|
-
insetBlockStart: ".1em",
|
|
2364
|
-
blockSize: "1.4em",
|
|
2365
|
-
verticalAlign: "top"
|
|
2366
|
-
},
|
|
2367
|
-
".cm-yLineSelection": {
|
|
2368
|
-
margin: 0
|
|
2369
|
-
},
|
|
2370
|
-
//
|
|
2371
2280
|
// link
|
|
2372
2281
|
//
|
|
2373
2282
|
".cm-link": {
|
|
@@ -2404,13 +2313,6 @@ var defaultTheme = {
|
|
|
2404
2313
|
textDecoration: "none"
|
|
2405
2314
|
},
|
|
2406
2315
|
//
|
|
2407
|
-
// widgets
|
|
2408
|
-
//
|
|
2409
|
-
".cm-widgetBuffer": {
|
|
2410
|
-
display: "none",
|
|
2411
|
-
height: 0
|
|
2412
|
-
},
|
|
2413
|
-
//
|
|
2414
2316
|
// table
|
|
2415
2317
|
//
|
|
2416
2318
|
".cm-table *": {
|
|
@@ -2441,27 +2343,17 @@ var defaultTheme = {
|
|
|
2441
2343
|
},
|
|
2442
2344
|
//
|
|
2443
2345
|
// font size
|
|
2444
|
-
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
2346
|
+
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
2347
|
+
// but it's far more verbose than it needs to be.
|
|
2445
2348
|
//
|
|
2446
|
-
...Object.keys(
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = {
|
|
2455
|
-
height
|
|
2456
|
-
};
|
|
2457
|
-
acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = {
|
|
2458
|
-
height
|
|
2459
|
-
};
|
|
2460
|
-
acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = {
|
|
2461
|
-
height
|
|
2462
|
-
};
|
|
2463
|
-
return acc;
|
|
2464
|
-
}, {}),
|
|
2349
|
+
// ...Object.keys(get(tokens, 'extend.fontSize', {})).reduce((acc: Record<string, any>, fontSize) => {
|
|
2350
|
+
// const height = get(tokens, ['extend', 'fontSize', fontSize, 1, 'lineHeight']);
|
|
2351
|
+
//
|
|
2352
|
+
// acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = { height };
|
|
2353
|
+
// acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = { height };
|
|
2354
|
+
// acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = { height };
|
|
2355
|
+
// return acc;
|
|
2356
|
+
// }, {}),
|
|
2465
2357
|
/**
|
|
2466
2358
|
* Panels
|
|
2467
2359
|
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
@@ -2512,7 +2404,9 @@ var textTheme = {
|
|
|
2512
2404
|
}
|
|
2513
2405
|
};
|
|
2514
2406
|
var markdownTheme = {
|
|
2515
|
-
|
|
2407
|
+
".cm-scroller": {
|
|
2408
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2409
|
+
},
|
|
2516
2410
|
".cm-placeholder": {
|
|
2517
2411
|
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2518
2412
|
}
|
|
@@ -2531,21 +2425,23 @@ var EditorModes = [
|
|
|
2531
2425
|
"default",
|
|
2532
2426
|
"vim"
|
|
2533
2427
|
];
|
|
2534
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
|
|
2535
|
-
const { themeMode } = useThemeContext();
|
|
2428
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, focus, selection, readonly, comments: comments2, extensions = [], editorMode, theme, slots = defaultSlots }, forwardedRef) => {
|
|
2536
2429
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
2537
2430
|
tabBehavior: "limited"
|
|
2538
2431
|
});
|
|
2539
|
-
const
|
|
2540
|
-
const
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
state,
|
|
2432
|
+
const { themeMode } = useThemeContext();
|
|
2433
|
+
const rootRef = useRef(null);
|
|
2434
|
+
const [view, setView] = useState(null);
|
|
2435
|
+
useImperativeHandle(forwardedRef, () => view, [
|
|
2544
2436
|
view
|
|
2545
|
-
|
|
2437
|
+
]);
|
|
2438
|
+
useEffect(() => {
|
|
2439
|
+
if (view && focus) {
|
|
2440
|
+
view.focus();
|
|
2441
|
+
}
|
|
2442
|
+
}, [
|
|
2546
2443
|
view,
|
|
2547
|
-
|
|
2548
|
-
root
|
|
2444
|
+
focus
|
|
2549
2445
|
]);
|
|
2550
2446
|
const { awareness: awareness2, peer } = model;
|
|
2551
2447
|
useEffect(() => {
|
|
@@ -2569,7 +2465,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2569
2465
|
themeMode
|
|
2570
2466
|
]);
|
|
2571
2467
|
useEffect(() => {
|
|
2572
|
-
if (view && comments2
|
|
2468
|
+
if (view && comments2 !== void 0) {
|
|
2573
2469
|
view.dispatch({
|
|
2574
2470
|
effects: setCommentRange.of({
|
|
2575
2471
|
model,
|
|
@@ -2582,11 +2478,13 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2582
2478
|
comments2
|
|
2583
2479
|
]);
|
|
2584
2480
|
useEffect(() => {
|
|
2585
|
-
if (!
|
|
2481
|
+
if (!model || !rootRef.current) {
|
|
2586
2482
|
return;
|
|
2587
2483
|
}
|
|
2588
|
-
const
|
|
2484
|
+
const state = EditorState2.create({
|
|
2589
2485
|
doc: model.text(),
|
|
2486
|
+
// TODO(burdon): Composer should store and set selection when switching documents.
|
|
2487
|
+
selection,
|
|
2590
2488
|
extensions: [
|
|
2591
2489
|
readonly && EditorState2.readOnly.of(readonly),
|
|
2592
2490
|
// TODO(burdon): Factor out VIM mode? (manage via MarkdownPlugin).
|
|
@@ -2594,7 +2492,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2594
2492
|
// Theme.
|
|
2595
2493
|
// TODO(burdon): Make theme configurable.
|
|
2596
2494
|
EditorView12.baseTheme(defaultTheme),
|
|
2597
|
-
EditorView12.theme(
|
|
2495
|
+
EditorView12.theme(theme ?? {}),
|
|
2598
2496
|
EditorView12.darkTheme.of(themeMode === "dark"),
|
|
2599
2497
|
// Storage and replication.
|
|
2600
2498
|
model.extension,
|
|
@@ -2603,19 +2501,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2603
2501
|
].filter(Boolean)
|
|
2604
2502
|
});
|
|
2605
2503
|
view?.destroy();
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
state: state2,
|
|
2610
|
-
parent: root
|
|
2611
|
-
})
|
|
2504
|
+
const newView = new EditorView12({
|
|
2505
|
+
parent: rootRef.current,
|
|
2506
|
+
state
|
|
2612
2507
|
});
|
|
2508
|
+
setView(newView);
|
|
2613
2509
|
return () => {
|
|
2614
|
-
|
|
2615
|
-
|
|
2510
|
+
newView?.destroy();
|
|
2511
|
+
setView(null);
|
|
2616
2512
|
};
|
|
2617
2513
|
}, [
|
|
2618
|
-
|
|
2514
|
+
rootRef,
|
|
2619
2515
|
model,
|
|
2620
2516
|
readonly,
|
|
2621
2517
|
editorMode,
|
|
@@ -2624,12 +2520,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2624
2520
|
const handleKeyUp = useCallback((event) => {
|
|
2625
2521
|
const { key, altKey, shiftKey, metaKey, ctrlKey } = event;
|
|
2626
2522
|
switch (key) {
|
|
2627
|
-
case "Enter": {
|
|
2628
|
-
view?.contentDOM.focus();
|
|
2629
|
-
break;
|
|
2630
|
-
}
|
|
2631
2523
|
case "Escape": {
|
|
2632
|
-
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) &&
|
|
2524
|
+
editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && rootRef.current?.focus();
|
|
2633
2525
|
break;
|
|
2634
2526
|
}
|
|
2635
2527
|
}
|
|
@@ -2639,16 +2531,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
|
|
|
2639
2531
|
]);
|
|
2640
2532
|
return /* @__PURE__ */ React.createElement("div", {
|
|
2641
2533
|
key: model.id,
|
|
2642
|
-
|
|
2534
|
+
role: "none",
|
|
2535
|
+
ref: rootRef,
|
|
2643
2536
|
tabIndex: 0,
|
|
2644
|
-
|
|
2645
|
-
...
|
|
2646
|
-
|
|
2537
|
+
onKeyUp: handleKeyUp,
|
|
2538
|
+
...slots.root,
|
|
2539
|
+
...editorMode !== "vim" && tabsterDOMAttribute
|
|
2647
2540
|
});
|
|
2648
2541
|
});
|
|
2649
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [],
|
|
2542
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, extensions = [], theme = textTheme, slots, ...props }, forwardedRef) => {
|
|
2650
2543
|
const { themeMode } = useThemeContext();
|
|
2651
|
-
const
|
|
2544
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
|
|
2652
2545
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2653
2546
|
ref: forwardedRef,
|
|
2654
2547
|
readonly,
|
|
@@ -2656,17 +2549,18 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
|
|
|
2656
2549
|
basicBundle({
|
|
2657
2550
|
readonly,
|
|
2658
2551
|
themeMode,
|
|
2659
|
-
placeholder:
|
|
2552
|
+
placeholder: placeholder3
|
|
2660
2553
|
}),
|
|
2661
2554
|
...extensions
|
|
2662
2555
|
],
|
|
2663
|
-
|
|
2556
|
+
theme,
|
|
2557
|
+
slots: updatedSlots,
|
|
2664
2558
|
...props
|
|
2665
2559
|
});
|
|
2666
2560
|
});
|
|
2667
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [],
|
|
2561
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, extensions = [], theme = markdownTheme, slots, ...props }, forwardedRef) => {
|
|
2668
2562
|
const { themeMode } = useThemeContext();
|
|
2669
|
-
const
|
|
2563
|
+
const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
|
|
2670
2564
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
2671
2565
|
ref: forwardedRef,
|
|
2672
2566
|
readonly,
|
|
@@ -2674,30 +2568,25 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
2674
2568
|
markdownBundle({
|
|
2675
2569
|
readonly,
|
|
2676
2570
|
themeMode,
|
|
2677
|
-
placeholder:
|
|
2571
|
+
placeholder: placeholder3
|
|
2678
2572
|
}),
|
|
2679
2573
|
...extensions
|
|
2680
2574
|
],
|
|
2681
|
-
|
|
2575
|
+
theme,
|
|
2576
|
+
slots: updatedSlots,
|
|
2682
2577
|
...props
|
|
2683
2578
|
});
|
|
2684
2579
|
});
|
|
2685
2580
|
var defaultSlots = {
|
|
2686
2581
|
root: {
|
|
2687
|
-
className: mx3("p-2", inputSurface)
|
|
2582
|
+
className: mx3("p-2 overflow-y-auto", inputSurface)
|
|
2688
2583
|
}
|
|
2689
2584
|
};
|
|
2690
2585
|
var defaultTextSlots = {
|
|
2691
|
-
...defaultSlots
|
|
2692
|
-
editor: {
|
|
2693
|
-
theme: textTheme
|
|
2694
|
-
}
|
|
2586
|
+
...defaultSlots
|
|
2695
2587
|
};
|
|
2696
2588
|
var defaultMarkdownSlots = {
|
|
2697
|
-
...defaultSlots
|
|
2698
|
-
editor: {
|
|
2699
|
-
theme: markdownTheme
|
|
2700
|
-
}
|
|
2589
|
+
...defaultSlots
|
|
2701
2590
|
};
|
|
2702
2591
|
|
|
2703
2592
|
// packages/ui/react-ui-editor/src/hooks/automerge.ts
|
|
@@ -2820,15 +2709,13 @@ import * as decoding from "lib0/decoding";
|
|
|
2820
2709
|
import * as encoding from "lib0/encoding";
|
|
2821
2710
|
import { Observable } from "lib0/observable";
|
|
2822
2711
|
import * as YP from "y-protocols/awareness";
|
|
2823
|
-
import * as Y2 from "yjs";
|
|
2824
2712
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
2825
2713
|
import { log as log4 } from "@dxos/log";
|
|
2826
|
-
import { arrayToString as arrayToString2, stringToArray as stringToArray2 } from "@dxos/util";
|
|
2827
2714
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs.ts";
|
|
2828
2715
|
var createYjsModel = ({ identity, space, text }) => {
|
|
2829
2716
|
invariant4(text?.doc && text?.content, void 0, {
|
|
2830
2717
|
F: __dxlog_file5,
|
|
2831
|
-
L:
|
|
2718
|
+
L: 21,
|
|
2832
2719
|
S: void 0,
|
|
2833
2720
|
A: [
|
|
2834
2721
|
"text?.doc && text?.content",
|
|
@@ -2844,34 +2731,6 @@ var createYjsModel = ({ identity, space, text }) => {
|
|
|
2844
2731
|
id: text.doc.guid,
|
|
2845
2732
|
content: text.content,
|
|
2846
2733
|
text: () => text.content.toString(),
|
|
2847
|
-
// https://github.com/yjs/yjs?tab=readme-ov-file#relative-positions
|
|
2848
|
-
// TODO(dmaretskyi): Refactor as cursor-converter.
|
|
2849
|
-
getCursorFromRange: (range) => {
|
|
2850
|
-
const from = Y2.encodeRelativePosition(Y2.createRelativePositionFromTypeIndex(text.content, range.from));
|
|
2851
|
-
const to = Y2.encodeRelativePosition(Y2.createRelativePositionFromTypeIndex(text.content, range.to, -1));
|
|
2852
|
-
return [
|
|
2853
|
-
arrayToString2(from),
|
|
2854
|
-
arrayToString2(to)
|
|
2855
|
-
].join(":");
|
|
2856
|
-
},
|
|
2857
|
-
getRangeFromCursor: (cursor) => {
|
|
2858
|
-
invariant4(text.doc, void 0, {
|
|
2859
|
-
F: __dxlog_file5,
|
|
2860
|
-
L: 40,
|
|
2861
|
-
S: void 0,
|
|
2862
|
-
A: [
|
|
2863
|
-
"text.doc",
|
|
2864
|
-
""
|
|
2865
|
-
]
|
|
2866
|
-
});
|
|
2867
|
-
const parts = cursor.split(":");
|
|
2868
|
-
const from = Y2.createAbsolutePositionFromRelativePosition(Y2.decodeRelativePosition(stringToArray2(parts[0])), text.doc);
|
|
2869
|
-
const to = Y2.createAbsolutePositionFromRelativePosition(Y2.decodeRelativePosition(stringToArray2(parts[1])), text.doc);
|
|
2870
|
-
return from && to ? {
|
|
2871
|
-
from: from.index,
|
|
2872
|
-
to: to.index
|
|
2873
|
-
} : void 0;
|
|
2874
|
-
},
|
|
2875
2734
|
extension: [
|
|
2876
2735
|
modelState.init(() => model),
|
|
2877
2736
|
yjs(text.content, provider?.awareness)
|
|
@@ -2921,7 +2780,7 @@ var YAwarenessProvider = class extends Observable {
|
|
|
2921
2780
|
origin
|
|
2922
2781
|
}, {
|
|
2923
2782
|
F: __dxlog_file5,
|
|
2924
|
-
L:
|
|
2783
|
+
L: 100,
|
|
2925
2784
|
S: this,
|
|
2926
2785
|
C: (f, a) => f(...a)
|
|
2927
2786
|
});
|
|
@@ -2934,7 +2793,7 @@ var YAwarenessProvider = class extends Observable {
|
|
|
2934
2793
|
_handleSpaceMessage({ payload }) {
|
|
2935
2794
|
log4("space message", payload, {
|
|
2936
2795
|
F: __dxlog_file5,
|
|
2937
|
-
L:
|
|
2796
|
+
L: 109,
|
|
2938
2797
|
S: this,
|
|
2939
2798
|
C: (f, a) => f(...a)
|
|
2940
2799
|
});
|
|
@@ -2984,7 +2843,7 @@ var modelState = StateField5.define({
|
|
|
2984
2843
|
});
|
|
2985
2844
|
var useTextModel = (props) => {
|
|
2986
2845
|
const { identity, space, text } = props;
|
|
2987
|
-
const [model, setModel] = useState2(
|
|
2846
|
+
const [model, setModel] = useState2();
|
|
2988
2847
|
useEffect2(() => setModel(createModel(props)), [
|
|
2989
2848
|
identity,
|
|
2990
2849
|
space,
|
|
@@ -3043,7 +2902,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
|
|
|
3043
2902
|
export {
|
|
3044
2903
|
AwarenessProvider,
|
|
3045
2904
|
BaseTextEditor,
|
|
3046
|
-
|
|
2905
|
+
Cursor,
|
|
3047
2906
|
Doc,
|
|
3048
2907
|
EditorModes,
|
|
3049
2908
|
MarkdownEditor,
|