@dxos/react-ui-editor 0.3.10-main.ee543cf → 0.3.10-main.fe592a2
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 +1417 -387
- 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 +26 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +3 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +3 -0
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts +3 -2
- package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/basic.d.ts +2 -1
- package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts +25 -0
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/code.d.ts +2 -0
- package/dist/types/src/components/TextEditor/extensions/code.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts +18 -0
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts +11 -0
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts +1 -1
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts +24 -0
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/image.d.ts +4 -0
- package/dist/types/src/components/TextEditor/extensions/image.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +8 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/link.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts +4 -2
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts +10 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts +9 -3
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/mention.d.ts +6 -0
- package/dist/types/src/components/TextEditor/extensions/mention.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/table.d.ts +8 -0
- package/dist/types/src/components/TextEditor/extensions/table.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts +2 -4
- package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/themes/default.d.ts +8 -0
- package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts +3 -0
- package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts +8 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/index.d.ts +1 -1
- package/dist/types/src/hooks/automerge/index.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/plugin.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts +5 -0
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts +6 -0
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/translation/index.d.ts +3 -0
- package/dist/types/src/hooks/automerge/translation/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts +6 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor → hooks/yjs}/yjs.stories.d.ts +2 -2
- package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +1 -0
- package/dist/types/src/styles/markdown.d.ts +3 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/testing/replicator.d.ts.map +1 -1
- package/package.json +22 -19
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +161 -36
- package/src/components/TextEditor/TextEditor.stories.tsx +12 -1
- package/src/components/TextEditor/TextEditor.tsx +43 -15
- package/src/components/TextEditor/extensions/autocomplete.ts +9 -22
- package/src/components/TextEditor/extensions/basic.ts +6 -4
- package/src/components/TextEditor/extensions/blast.ts +373 -0
- package/src/components/TextEditor/extensions/code.ts +99 -0
- package/src/components/TextEditor/extensions/comments.ts +173 -0
- package/src/components/TextEditor/extensions/demo.ts +69 -0
- package/src/components/TextEditor/extensions/experimental.tsx +15 -35
- package/src/components/TextEditor/extensions/highlight.ts +128 -0
- package/src/components/TextEditor/extensions/image.ts +67 -0
- package/src/components/TextEditor/extensions/index.ts +8 -0
- package/src/components/TextEditor/extensions/link.ts +27 -27
- package/src/components/TextEditor/extensions/listener.ts +4 -3
- package/src/components/TextEditor/extensions/markdown/bundle.ts +47 -53
- package/src/components/TextEditor/extensions/markdown/highlight.ts +148 -107
- package/src/components/TextEditor/extensions/mention.ts +31 -0
- package/src/components/TextEditor/extensions/table.ts +119 -0
- package/src/components/TextEditor/extensions/tasklist.ts +89 -81
- package/src/components/TextEditor/themes/default.ts +112 -4
- package/src/hooks/automerge/PatchSemaphore.ts +12 -9
- package/src/hooks/automerge/automerge.stories.tsx +4 -2
- package/src/hooks/automerge/index.ts +1 -1
- package/src/hooks/automerge/plugin.ts +1 -0
- package/src/hooks/automerge/{amToCodemirror.ts → translation/automerge-to-codemirror.ts} +10 -2
- package/src/hooks/automerge/{codeMirrorToAm.ts → translation/codemirror-to-automerge.ts} +7 -4
- package/src/hooks/automerge/translation/index.ts +6 -0
- package/src/hooks/useTextModel.ts +20 -8
- package/src/{components/TextEditor → hooks/yjs}/yjs.stories.tsx +2 -2
- package/src/styles/markdown.ts +15 -8
- package/src/testing/replicator.ts +6 -5
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/amToCodemirror.d.ts +0 -6
- package/dist/types/src/hooks/automerge/amToCodemirror.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts +0 -7
- package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts.map +0 -1
|
@@ -8,7 +8,7 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
|
8
8
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/autocomplete.ts
|
|
9
9
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
10
10
|
import { keymap } from "@codemirror/view";
|
|
11
|
-
var autocomplete = ({
|
|
11
|
+
var autocomplete = ({ onSearch }) => {
|
|
12
12
|
return [
|
|
13
13
|
// https://codemirror.net/docs/ref/#view.keymap
|
|
14
14
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
|
@@ -24,13 +24,13 @@ var autocomplete = ({ getOptions }) => {
|
|
|
24
24
|
// TODO(burdon): Optional decoration via addToOptions
|
|
25
25
|
override: [
|
|
26
26
|
(context) => {
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
27
|
+
const match = context.matchBefore(/\w*/);
|
|
28
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
31
|
return {
|
|
32
|
-
from:
|
|
33
|
-
options:
|
|
32
|
+
from: match.from,
|
|
33
|
+
options: onSearch(match.text.toLowerCase())
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
]
|
|
@@ -42,23 +42,809 @@ var autocomplete = ({ getOptions }) => {
|
|
|
42
42
|
import { closeBrackets } from "@codemirror/autocomplete";
|
|
43
43
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
44
44
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
45
|
-
import { EditorView, placeholder } from "@codemirror/view";
|
|
46
|
-
var basicBundle = ({ themeMode, placeholder: _placeholder }) => [
|
|
45
|
+
import { drawSelection, EditorView, placeholder } from "@codemirror/view";
|
|
46
|
+
var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
|
|
47
|
+
EditorView.lineWrapping,
|
|
47
48
|
// TODO(burdon): Compare with minimalSetup.
|
|
48
49
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
49
50
|
bracketMatching(),
|
|
50
51
|
closeBrackets(),
|
|
51
|
-
|
|
52
|
+
drawSelection(),
|
|
52
53
|
_placeholder && placeholder(_placeholder),
|
|
53
54
|
// TODO(burdon): Is this required?
|
|
54
55
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
55
56
|
].filter(Boolean);
|
|
56
57
|
|
|
57
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/
|
|
58
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts
|
|
59
|
+
import { EditorView as EditorView2, keymap as keymap2 } from "@codemirror/view";
|
|
60
|
+
import defaultsDeep from "lodash.defaultsdeep";
|
|
61
|
+
import { invariant } from "@dxos/invariant";
|
|
62
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts";
|
|
63
|
+
var defaultOptions = {
|
|
64
|
+
effect: 2,
|
|
65
|
+
maxParticles: 200,
|
|
66
|
+
particleGravity: 0.08,
|
|
67
|
+
particleAlphaFadeout: 0.996,
|
|
68
|
+
particleSize: {
|
|
69
|
+
min: 2,
|
|
70
|
+
max: 8
|
|
71
|
+
},
|
|
72
|
+
particleNumRange: {
|
|
73
|
+
min: 5,
|
|
74
|
+
max: 10
|
|
75
|
+
},
|
|
76
|
+
particleVelocityRange: {
|
|
77
|
+
x: [
|
|
78
|
+
-1,
|
|
79
|
+
1
|
|
80
|
+
],
|
|
81
|
+
y: [
|
|
82
|
+
-3.5,
|
|
83
|
+
-1.5
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
particleShrinkRate: 0.95,
|
|
87
|
+
shakeIntensity: 5
|
|
88
|
+
};
|
|
89
|
+
var blast = (options = defaultOptions) => {
|
|
90
|
+
let blaster;
|
|
91
|
+
let last = 0;
|
|
92
|
+
const getPoint = (view, pos) => {
|
|
93
|
+
const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
|
|
94
|
+
const element = document.elementFromPoint(x, y);
|
|
95
|
+
const { offsetLeft: left = 0, offsetTop: top = 0 } = view.scrollDOM.parentElement ?? {};
|
|
96
|
+
const point = {
|
|
97
|
+
x: x - left,
|
|
98
|
+
y: y - top
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
element,
|
|
102
|
+
point
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
return [
|
|
106
|
+
// Cursor moved.
|
|
107
|
+
EditorView2.updateListener.of((update4) => {
|
|
108
|
+
if (blaster?.node !== update4.view.scrollDOM) {
|
|
109
|
+
if (blaster) {
|
|
110
|
+
blaster.destroy();
|
|
111
|
+
}
|
|
112
|
+
blaster = new Blaster(update4.view.scrollDOM, defaultsDeep({
|
|
113
|
+
particleGravity: 0.2,
|
|
114
|
+
particleShrinkRate: 0.995,
|
|
115
|
+
color: () => [
|
|
116
|
+
100 + Math.random() * 100,
|
|
117
|
+
0,
|
|
118
|
+
0
|
|
119
|
+
]
|
|
120
|
+
}, options, defaultOptions));
|
|
121
|
+
blaster.initialize();
|
|
122
|
+
blaster.start();
|
|
123
|
+
} else {
|
|
124
|
+
blaster.resize();
|
|
125
|
+
}
|
|
126
|
+
const current = update4.state.selection.main.head;
|
|
127
|
+
if (current !== last) {
|
|
128
|
+
last = current;
|
|
129
|
+
const { element, point } = getPoint(update4.view, current - 1);
|
|
130
|
+
if (element && point) {
|
|
131
|
+
blaster.spawn({
|
|
132
|
+
element,
|
|
133
|
+
point
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}),
|
|
138
|
+
keymap2.of([
|
|
139
|
+
{
|
|
140
|
+
any: (_, event) => {
|
|
141
|
+
if (blaster) {
|
|
142
|
+
if (event.key === "Enter" && event.shiftKey) {
|
|
143
|
+
blaster.shake({
|
|
144
|
+
time: 0.8
|
|
145
|
+
});
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
])
|
|
153
|
+
];
|
|
154
|
+
};
|
|
155
|
+
var Blaster = class {
|
|
156
|
+
constructor(_node, _options) {
|
|
157
|
+
this._node = _node;
|
|
158
|
+
this._options = _options;
|
|
159
|
+
this._running = false;
|
|
160
|
+
this._shakeTime = 0;
|
|
161
|
+
this._shakeTimeMax = 0;
|
|
162
|
+
this._particles = [];
|
|
163
|
+
this._particlePointer = 0;
|
|
164
|
+
this._lastPoint = {
|
|
165
|
+
x: 0,
|
|
166
|
+
y: 0
|
|
167
|
+
};
|
|
168
|
+
this.shake = throttle(({ time }) => {
|
|
169
|
+
this._shakeTime = this._shakeTimeMax || time;
|
|
170
|
+
this._shakeTimeMax = time;
|
|
171
|
+
}, 100);
|
|
172
|
+
this.spawn = throttle(({ element, point }) => {
|
|
173
|
+
const color = getRGBComponents(element, this._options.color);
|
|
174
|
+
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
175
|
+
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
176
|
+
this._lastPoint = point;
|
|
177
|
+
for (let i = numParticles; i--; i > 0) {
|
|
178
|
+
this._particles[this._particlePointer] = this._effect.create(point.x - dir * 16, point.y, color);
|
|
179
|
+
this._particlePointer = (this._particlePointer + 1) % this._options.maxParticles;
|
|
180
|
+
}
|
|
181
|
+
}, 100);
|
|
182
|
+
this._effect = this._options.effect === 1 ? new Effect1(_options) : new Effect2(_options);
|
|
183
|
+
}
|
|
184
|
+
get node() {
|
|
185
|
+
return this._node;
|
|
186
|
+
}
|
|
187
|
+
initialize() {
|
|
188
|
+
invariant(!this._canvas && !this._ctx, void 0, {
|
|
189
|
+
F: __dxlog_file,
|
|
190
|
+
L: 138,
|
|
191
|
+
S: this,
|
|
192
|
+
A: [
|
|
193
|
+
"!this._canvas && !this._ctx",
|
|
194
|
+
""
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
this._canvas = document.createElement("canvas");
|
|
198
|
+
this._canvas.id = "code-blast-canvas";
|
|
199
|
+
this._canvas.style.position = "absolute";
|
|
200
|
+
this._canvas.style.zIndex = "0";
|
|
201
|
+
this._canvas.style.pointerEvents = "none";
|
|
202
|
+
this._ctx = this._canvas.getContext("2d");
|
|
203
|
+
const parent = this._node.parentElement?.parentElement;
|
|
204
|
+
parent?.appendChild(this._canvas);
|
|
205
|
+
this.resize();
|
|
206
|
+
}
|
|
207
|
+
destroy() {
|
|
208
|
+
this.stop();
|
|
209
|
+
if (this._canvas) {
|
|
210
|
+
this._canvas.remove();
|
|
211
|
+
this._canvas = void 0;
|
|
212
|
+
this._ctx = void 0;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
resize() {
|
|
216
|
+
if (this._node.parentElement && this._canvas) {
|
|
217
|
+
const { offsetLeft: x, offsetTop: y, offsetWidth: width, offsetHeight: height } = this._node.parentElement;
|
|
218
|
+
this._canvas.style.top = `${y}px`;
|
|
219
|
+
this._canvas.style.left = `${x}px`;
|
|
220
|
+
this._canvas.width = width;
|
|
221
|
+
this._canvas.height = height;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
start() {
|
|
225
|
+
invariant(this._canvas && this._ctx, void 0, {
|
|
226
|
+
F: __dxlog_file,
|
|
227
|
+
L: 177,
|
|
228
|
+
S: this,
|
|
229
|
+
A: [
|
|
230
|
+
"this._canvas && this._ctx",
|
|
231
|
+
""
|
|
232
|
+
]
|
|
233
|
+
});
|
|
234
|
+
this._running = true;
|
|
235
|
+
this.loop();
|
|
236
|
+
}
|
|
237
|
+
stop() {
|
|
238
|
+
this._running = false;
|
|
239
|
+
this._node.style.transform = "translate(0px, 0px)";
|
|
240
|
+
}
|
|
241
|
+
loop() {
|
|
242
|
+
if (!this._running || !this._canvas || !this._ctx) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
this._ctx.clearRect(0, 0, this._canvas.width ?? 0, this._canvas.height ?? 0);
|
|
246
|
+
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
247
|
+
this._lastTime ??= now;
|
|
248
|
+
const dt = (now - this._lastTime) / 1e3;
|
|
249
|
+
this._lastTime = now;
|
|
250
|
+
if (this._shakeTime > 0) {
|
|
251
|
+
this._shakeTime -= dt;
|
|
252
|
+
const magnitude = this._shakeTime / this._shakeTimeMax * this._options.shakeIntensity;
|
|
253
|
+
const shakeX = random(-magnitude, magnitude);
|
|
254
|
+
const shakeY = random(-magnitude, magnitude);
|
|
255
|
+
this._node.style.transform = `translate(${shakeX}px,${shakeY}px)`;
|
|
256
|
+
}
|
|
257
|
+
this.drawParticles();
|
|
258
|
+
requestAnimationFrame(this.loop.bind(this));
|
|
259
|
+
}
|
|
260
|
+
drawParticles() {
|
|
261
|
+
for (let i = this._particles.length; i--; i > 0) {
|
|
262
|
+
const particle = this._particles[i];
|
|
263
|
+
if (!particle) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (particle.alpha < 0.01 || particle.size <= 0.5) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
this._effect.update(this._ctx, particle);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
var Effect = class {
|
|
274
|
+
constructor(_options) {
|
|
275
|
+
this._options = _options;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var Effect1 = class extends Effect {
|
|
279
|
+
create(x, y, color) {
|
|
280
|
+
return {
|
|
281
|
+
x,
|
|
282
|
+
y: y + 10,
|
|
283
|
+
vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),
|
|
284
|
+
vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),
|
|
285
|
+
size: random(this._options.particleSize.min, this._options.particleSize.max),
|
|
286
|
+
color,
|
|
287
|
+
alpha: 1
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
update(ctx, particle) {
|
|
291
|
+
particle.vy += this._options.particleGravity;
|
|
292
|
+
particle.x += particle.vx;
|
|
293
|
+
particle.y += particle.vy;
|
|
294
|
+
particle.alpha *= this._options.particleAlphaFadeout;
|
|
295
|
+
ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;
|
|
296
|
+
ctx.fillRect(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, particle.size);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
var Effect2 = class extends Effect {
|
|
300
|
+
create(x, y, color) {
|
|
301
|
+
return {
|
|
302
|
+
x,
|
|
303
|
+
y: y + 10,
|
|
304
|
+
vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),
|
|
305
|
+
vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),
|
|
306
|
+
size: random(this._options.particleSize.min, this._options.particleSize.max),
|
|
307
|
+
color,
|
|
308
|
+
alpha: 1,
|
|
309
|
+
theta: random(0, 360) * Math.PI / 180,
|
|
310
|
+
drag: 0.92,
|
|
311
|
+
wander: 0.15
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
update(ctx, particle) {
|
|
315
|
+
particle.vy += this._options.particleGravity;
|
|
316
|
+
particle.x += particle.vx;
|
|
317
|
+
particle.y += particle.vy;
|
|
318
|
+
particle.vx *= particle.drag;
|
|
319
|
+
particle.vy *= particle.drag;
|
|
320
|
+
particle.theta += random(-0.5, 0.5);
|
|
321
|
+
particle.vx += Math.sin(particle.theta) * 0.1;
|
|
322
|
+
particle.vy += Math.cos(particle.theta) * 0.1;
|
|
323
|
+
particle.size *= this._options.particleShrinkRate;
|
|
324
|
+
particle.alpha *= this._options.particleAlphaFadeout;
|
|
325
|
+
ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;
|
|
326
|
+
ctx.beginPath();
|
|
327
|
+
ctx.arc(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, 0, 2 * Math.PI);
|
|
328
|
+
ctx.fill();
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
function throttle(callback, limit) {
|
|
332
|
+
let wait = false;
|
|
333
|
+
return function(...args) {
|
|
334
|
+
if (!wait) {
|
|
335
|
+
callback.apply(this, args);
|
|
336
|
+
wait = true;
|
|
337
|
+
setTimeout(() => {
|
|
338
|
+
wait = false;
|
|
339
|
+
}, limit);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
var getRGBComponents = (node, color) => {
|
|
344
|
+
if (typeof color === "function") {
|
|
345
|
+
return color();
|
|
346
|
+
}
|
|
347
|
+
const bgColor = getComputedStyle(node).color;
|
|
348
|
+
if (bgColor) {
|
|
349
|
+
const x = bgColor.match(/(\d+), (\d+), (\d+)/)?.slice(1);
|
|
350
|
+
if (x) {
|
|
351
|
+
return x;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return [
|
|
355
|
+
50,
|
|
356
|
+
50,
|
|
357
|
+
50
|
|
358
|
+
];
|
|
359
|
+
};
|
|
360
|
+
var random = (min, max) => {
|
|
361
|
+
if (!max) {
|
|
362
|
+
max = min;
|
|
363
|
+
min = 0;
|
|
364
|
+
}
|
|
365
|
+
return min + ~~(Math.random() * (max - min + 1));
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/code.ts
|
|
369
|
+
import { ViewPlugin, EditorView as EditorView3, Decoration } from "@codemirror/view";
|
|
370
|
+
import get from "lodash.get";
|
|
371
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
372
|
+
|
|
373
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
374
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
375
|
+
var headings = {
|
|
376
|
+
1: [
|
|
377
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
378
|
+
"-ml-[10px]"
|
|
379
|
+
],
|
|
380
|
+
2: [
|
|
381
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
382
|
+
"-ml-[8px]"
|
|
383
|
+
],
|
|
384
|
+
3: [
|
|
385
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
386
|
+
"-ml-[7px]"
|
|
387
|
+
],
|
|
388
|
+
4: [
|
|
389
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
390
|
+
"-ml-[6px]"
|
|
391
|
+
],
|
|
392
|
+
5: [
|
|
393
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
394
|
+
"-ml-[5px]"
|
|
395
|
+
],
|
|
396
|
+
6: [
|
|
397
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline",
|
|
398
|
+
"-ml-[4px]"
|
|
399
|
+
]
|
|
400
|
+
};
|
|
401
|
+
var heading = (level, readonly) => {
|
|
402
|
+
const [style, offset] = headings[level];
|
|
403
|
+
return mx(style, readonly && offset);
|
|
404
|
+
};
|
|
405
|
+
var light = "text-neutral-200 dark:text-neutral-800";
|
|
406
|
+
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
407
|
+
var bold = "font-bold";
|
|
408
|
+
var italic = "italic";
|
|
409
|
+
var strikethrough = "line-through";
|
|
410
|
+
var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
|
|
411
|
+
var codeMark = "font-mono text-primary-500";
|
|
412
|
+
var inlineUrl = mx(code, "px-1");
|
|
413
|
+
var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
|
|
414
|
+
var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
|
|
415
|
+
|
|
416
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
417
|
+
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
418
|
+
var tokens = tailwindConfig({}).theme;
|
|
419
|
+
|
|
420
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/code.ts
|
|
421
|
+
var CODE_REGEX = /```[\s\S]*?```/gs;
|
|
422
|
+
var styles = EditorView3.baseTheme({
|
|
423
|
+
"& .cm-code-block": {
|
|
424
|
+
display: "block",
|
|
425
|
+
paddingInline: "4px !important"
|
|
426
|
+
},
|
|
427
|
+
"&light .cm-code-block": {
|
|
428
|
+
background: get(tokens, "extend.colors.neutral.50")
|
|
429
|
+
},
|
|
430
|
+
"&dark .cm-code-block": {
|
|
431
|
+
background: get(tokens, "extend.colors.neutral.850")
|
|
432
|
+
},
|
|
433
|
+
"& .cm-code-block-first": {
|
|
434
|
+
paddingTop: "4px !important",
|
|
435
|
+
borderTopLeftRadius: "4px",
|
|
436
|
+
borderTopRightRadius: "4px"
|
|
437
|
+
},
|
|
438
|
+
"& .cm-code-block-last": {
|
|
439
|
+
paddingBottom: "4px !important",
|
|
440
|
+
borderBottomLeftRadius: "4px",
|
|
441
|
+
borderBottomRightRadius: "4px"
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
var getLineRange = (lines, from, to) => {
|
|
445
|
+
const start = lines.findIndex((line) => line.from >= from);
|
|
446
|
+
const end = lines.findIndex((line) => line.to >= to);
|
|
447
|
+
return [
|
|
448
|
+
start,
|
|
449
|
+
end
|
|
450
|
+
];
|
|
451
|
+
};
|
|
452
|
+
var code2 = () => {
|
|
453
|
+
const getDecorations = (view) => {
|
|
454
|
+
const decorations = [];
|
|
455
|
+
if (view.state.readOnly) {
|
|
456
|
+
const text = view.state.doc.sliceString(0);
|
|
457
|
+
const matches = text.matchAll(CODE_REGEX);
|
|
458
|
+
const blocks = view.viewportLineBlocks;
|
|
459
|
+
for (const match of matches) {
|
|
460
|
+
const range = getLineRange(blocks, match.index, match.index + match[0].length);
|
|
461
|
+
for (let i = range[0]; i <= range[1]; i++) {
|
|
462
|
+
const block = blocks[i];
|
|
463
|
+
decorations.push(Decoration.line({
|
|
464
|
+
class: mx2("cm-code-block", i === range[0] && "cm-code-block-first", i === range[1] && "cm-code-block-last")
|
|
465
|
+
}).range(block.from));
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return Decoration.set(decorations);
|
|
470
|
+
};
|
|
471
|
+
return [
|
|
472
|
+
ViewPlugin.fromClass(class {
|
|
473
|
+
constructor(view) {
|
|
474
|
+
this.decorations = getDecorations(view);
|
|
475
|
+
}
|
|
476
|
+
update(update4) {
|
|
477
|
+
if (update4.docChanged || update4.viewportChanged) {
|
|
478
|
+
this.decorations = getDecorations(update4.view);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}, {
|
|
482
|
+
decorations: (value) => value.decorations
|
|
483
|
+
}),
|
|
484
|
+
styles
|
|
485
|
+
];
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/demo.ts
|
|
489
|
+
import { keymap as keymap3 } from "@codemirror/view";
|
|
490
|
+
var defaultItems = [
|
|
491
|
+
"hello world!",
|
|
492
|
+
"this is a test.",
|
|
493
|
+
"this is [DXOS](https://dxos.org)"
|
|
494
|
+
];
|
|
495
|
+
var demo = ({ delay = 75, items = defaultItems } = {}) => {
|
|
496
|
+
let t;
|
|
497
|
+
let idx = 0;
|
|
498
|
+
return [
|
|
499
|
+
keymap3.of([
|
|
500
|
+
{
|
|
501
|
+
// Reset.
|
|
502
|
+
key: "alt-meta-'",
|
|
503
|
+
run: (view) => {
|
|
504
|
+
clearTimeout(t);
|
|
505
|
+
idx = 0;
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
// Next prompt.
|
|
511
|
+
// TODO(burdon): Press 1-9 to select prompt?
|
|
512
|
+
key: "shift-meta-'",
|
|
513
|
+
run: (view) => {
|
|
514
|
+
clearTimeout(t);
|
|
515
|
+
const text = items[idx++];
|
|
516
|
+
if (idx === items?.length) {
|
|
517
|
+
idx = 0;
|
|
518
|
+
}
|
|
519
|
+
let i = 0;
|
|
520
|
+
const insert = (d = 0) => {
|
|
521
|
+
t = setTimeout(() => {
|
|
522
|
+
const pos = view.state.selection.main.head;
|
|
523
|
+
view.dispatch({
|
|
524
|
+
changes: {
|
|
525
|
+
from: pos,
|
|
526
|
+
insert: text[i++]
|
|
527
|
+
},
|
|
528
|
+
selection: {
|
|
529
|
+
anchor: pos + 1
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
if (i < text.length) {
|
|
533
|
+
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
534
|
+
}
|
|
535
|
+
}, d);
|
|
536
|
+
};
|
|
537
|
+
insert();
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
])
|
|
542
|
+
];
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts
|
|
546
|
+
import { keymap as keymap4, Decoration as Decoration2, EditorView as EditorView4, MatchDecorator, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
|
547
|
+
import { debounce } from "@dxos/async";
|
|
548
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
549
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts";
|
|
550
|
+
var styles2 = EditorView4.baseTheme({
|
|
551
|
+
"& .cm-bookmark": {
|
|
552
|
+
cursor: "pointer",
|
|
553
|
+
margin: "4px",
|
|
554
|
+
padding: "4px",
|
|
555
|
+
backgroundColor: "yellow"
|
|
556
|
+
},
|
|
557
|
+
"& .cm-bookmark-selected": {
|
|
558
|
+
backgroundColor: "orange"
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
var BookmarkWidget = class extends WidgetType {
|
|
562
|
+
constructor(_pos, _id, _handleClick) {
|
|
563
|
+
super();
|
|
564
|
+
this._pos = _pos;
|
|
565
|
+
this._id = _id;
|
|
566
|
+
this._handleClick = _handleClick;
|
|
567
|
+
invariant2(this._id, void 0, {
|
|
568
|
+
F: __dxlog_file2,
|
|
569
|
+
L: 37,
|
|
570
|
+
S: this,
|
|
571
|
+
A: [
|
|
572
|
+
"this._id",
|
|
573
|
+
""
|
|
574
|
+
]
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
eq(other) {
|
|
578
|
+
return this._id === other._id;
|
|
579
|
+
}
|
|
580
|
+
toDOM() {
|
|
581
|
+
const span = document.createElement("span");
|
|
582
|
+
span.className = "cm-bookmark";
|
|
583
|
+
span.textContent = "\xA7";
|
|
584
|
+
span.onclick = () => this._handleClick();
|
|
585
|
+
return span;
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
var comments = (options = {}) => {
|
|
589
|
+
let active;
|
|
590
|
+
const bookmarkMatcher = new MatchDecorator({
|
|
591
|
+
regexp: /\[\^(\w+)\]/g,
|
|
592
|
+
decoration: (match, view, pos) => {
|
|
593
|
+
const id = match[1];
|
|
594
|
+
return Decoration2.replace({
|
|
595
|
+
id,
|
|
596
|
+
widget: new BookmarkWidget(pos, id, () => handleUpdate({
|
|
597
|
+
active: id
|
|
598
|
+
}))
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
const bookmarks = ViewPlugin2.fromClass(class {
|
|
603
|
+
constructor(view) {
|
|
604
|
+
this.bookmarks = bookmarkMatcher.createDeco(view);
|
|
605
|
+
}
|
|
606
|
+
update(update4) {
|
|
607
|
+
this.bookmarks = bookmarkMatcher.updateDeco(update4, this.bookmarks);
|
|
608
|
+
}
|
|
609
|
+
}, {
|
|
610
|
+
decorations: (instance) => instance.bookmarks,
|
|
611
|
+
provide: (plugin) => EditorView4.atomicRanges.of((view) => {
|
|
612
|
+
return view.plugin(plugin)?.bookmarks || Decoration2.none;
|
|
613
|
+
})
|
|
614
|
+
});
|
|
615
|
+
const handleUpdate = debounce((data) => {
|
|
616
|
+
options.onUpdate?.(data);
|
|
617
|
+
}, 200);
|
|
618
|
+
return [
|
|
619
|
+
keymap4.of([
|
|
620
|
+
{
|
|
621
|
+
key: options?.key ?? "shift-meta-c",
|
|
622
|
+
run: (view) => {
|
|
623
|
+
const { from, to, head } = view.state.selection.main;
|
|
624
|
+
const id = options.onCreate?.(from, to);
|
|
625
|
+
if (id) {
|
|
626
|
+
const tag = `[^${id}]`;
|
|
627
|
+
view.dispatch({
|
|
628
|
+
changes: {
|
|
629
|
+
from: head,
|
|
630
|
+
insert: tag
|
|
631
|
+
},
|
|
632
|
+
selection: {
|
|
633
|
+
anchor: head + tag.length
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
return false;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
]),
|
|
642
|
+
bookmarks,
|
|
643
|
+
// Monitor cursor movement.
|
|
644
|
+
EditorView4.updateListener.of((update4) => {
|
|
645
|
+
active = void 0;
|
|
646
|
+
if (!options.onUpdate) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
const { view, state } = update4;
|
|
650
|
+
const pos = state.selection.main.head;
|
|
651
|
+
const decorations = [];
|
|
652
|
+
const rangeSet = view.plugin(bookmarks)?.bookmarks;
|
|
653
|
+
let closest = Infinity;
|
|
654
|
+
const { from, to } = (
|
|
655
|
+
/* view.visibleRanges?.[0] ?? */
|
|
656
|
+
{
|
|
657
|
+
from: 0,
|
|
658
|
+
to: state.doc.length
|
|
659
|
+
}
|
|
660
|
+
);
|
|
661
|
+
rangeSet?.between(from, to, (from2, to2, value) => {
|
|
662
|
+
decorations.push({
|
|
663
|
+
from: from2,
|
|
664
|
+
to: to2,
|
|
665
|
+
value
|
|
666
|
+
});
|
|
667
|
+
const d = Math.min(Math.abs(pos - from2), Math.abs(pos - to2));
|
|
668
|
+
if (d < closest) {
|
|
669
|
+
active = value.spec.id;
|
|
670
|
+
closest = d;
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
if (decorations.length) {
|
|
674
|
+
handleUpdate({
|
|
675
|
+
active,
|
|
676
|
+
items: decorations.map(({ from: from2, value: { spec: { id } } }) => ({
|
|
677
|
+
id,
|
|
678
|
+
pos: from2,
|
|
679
|
+
location: view.coordsAtPos(from2)
|
|
680
|
+
}))
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
}),
|
|
684
|
+
styles2
|
|
685
|
+
];
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/highlight.ts
|
|
689
|
+
import { StateEffect, StateField } from "@codemirror/state";
|
|
690
|
+
import { Decoration as Decoration3, EditorView as EditorView5 } from "@codemirror/view";
|
|
691
|
+
import sortBy from "lodash.sortby";
|
|
692
|
+
import { useEffect } from "react";
|
|
693
|
+
var styles3 = EditorView5.baseTheme({
|
|
694
|
+
"& .cm-highlight": {
|
|
695
|
+
backgroundColor: "yellow"
|
|
696
|
+
},
|
|
697
|
+
"& .cm-highlight::before": {
|
|
698
|
+
content: "]"
|
|
699
|
+
},
|
|
700
|
+
"& .cm-highlight-active": {
|
|
701
|
+
backgroundColor: "lime"
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
var marks = {
|
|
705
|
+
highlight: Decoration3.mark({
|
|
706
|
+
class: "cm-highlight"
|
|
707
|
+
}),
|
|
708
|
+
HighlightActive: Decoration3.mark({
|
|
709
|
+
class: "cm-highlight-active"
|
|
710
|
+
})
|
|
711
|
+
};
|
|
712
|
+
var setHighlights = StateEffect.define();
|
|
713
|
+
var useHighlights = (view, ranges = []) => {
|
|
714
|
+
useEffect(() => {
|
|
715
|
+
view?.dispatch({
|
|
716
|
+
effects: setHighlights.of(ranges)
|
|
717
|
+
});
|
|
718
|
+
}, [
|
|
719
|
+
view,
|
|
720
|
+
ranges
|
|
721
|
+
]);
|
|
722
|
+
};
|
|
723
|
+
var highlightStateField = StateField.define({
|
|
724
|
+
create: () => [],
|
|
725
|
+
update: (threads, tr) => {
|
|
726
|
+
for (const effect of tr.effects) {
|
|
727
|
+
if (effect.is(setHighlights)) {
|
|
728
|
+
return effect.value;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return threads;
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
var highlightDecorations = EditorView5.decorations.compute([
|
|
735
|
+
highlightStateField
|
|
736
|
+
], (state) => {
|
|
737
|
+
const selectionRanges = state.field(highlightStateField);
|
|
738
|
+
const decorations = sortBy(selectionRanges ?? [], (selection) => selection.from)?.flatMap((selection) => {
|
|
739
|
+
const range = {
|
|
740
|
+
from: selection.from,
|
|
741
|
+
to: selection.to + 1
|
|
742
|
+
};
|
|
743
|
+
if (selection.to > selection.from) {
|
|
744
|
+
if (selection.active) {
|
|
745
|
+
return marks.HighlightActive.range(range.from, range.to);
|
|
746
|
+
} else {
|
|
747
|
+
return marks.highlight.range(range.from, range.to);
|
|
748
|
+
}
|
|
749
|
+
} else {
|
|
750
|
+
return [];
|
|
751
|
+
}
|
|
752
|
+
}) ?? [];
|
|
753
|
+
return Decoration3.set(decorations);
|
|
754
|
+
});
|
|
755
|
+
var listener = (options) => {
|
|
756
|
+
return EditorView5.updateListener.of((update4) => {
|
|
757
|
+
const { view, state } = update4;
|
|
758
|
+
const { head } = state.selection.main;
|
|
759
|
+
const ranges = state.field(highlightStateField);
|
|
760
|
+
let mod = false;
|
|
761
|
+
const newRanges = ranges.map((range) => {
|
|
762
|
+
const active = head >= range.from && head <= range.to;
|
|
763
|
+
if (active !== range.active) {
|
|
764
|
+
mod = true;
|
|
765
|
+
return {
|
|
766
|
+
...range,
|
|
767
|
+
active
|
|
768
|
+
};
|
|
769
|
+
} else {
|
|
770
|
+
return range;
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
if (mod) {
|
|
774
|
+
view.dispatch({
|
|
775
|
+
effects: setHighlights.of(newRanges)
|
|
776
|
+
});
|
|
777
|
+
options?.onChange?.(newRanges.find((range) => range.active)?.id);
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
};
|
|
781
|
+
var highlight = (options = {}) => {
|
|
782
|
+
return [
|
|
783
|
+
highlightStateField,
|
|
784
|
+
highlightDecorations,
|
|
785
|
+
listener(options),
|
|
786
|
+
styles3
|
|
787
|
+
];
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/image.ts
|
|
58
791
|
import { syntaxTree } from "@codemirror/language";
|
|
59
|
-
import { RangeSetBuilder, StateField } from "@codemirror/state";
|
|
60
|
-
import { Decoration, EditorView as
|
|
61
|
-
var
|
|
792
|
+
import { RangeSetBuilder, StateField as StateField2 } from "@codemirror/state";
|
|
793
|
+
import { Decoration as Decoration4, EditorView as EditorView6, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
794
|
+
var image = (options = {}) => {
|
|
795
|
+
return StateField2.define({
|
|
796
|
+
create: (state) => update(state, options),
|
|
797
|
+
update: (_, tr) => update(tr.state, options),
|
|
798
|
+
provide: (field) => EditorView6.decorations.from(field)
|
|
799
|
+
});
|
|
800
|
+
};
|
|
801
|
+
var update = (state, options) => {
|
|
802
|
+
const builder = new RangeSetBuilder();
|
|
803
|
+
const cursor = state.selection.main.head;
|
|
804
|
+
syntaxTree(state).iterate({
|
|
805
|
+
enter: (node) => {
|
|
806
|
+
if (node.name === "Image") {
|
|
807
|
+
const urlNode = node.node.getChild("URL");
|
|
808
|
+
if (urlNode) {
|
|
809
|
+
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
810
|
+
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
811
|
+
builder.add(hide ? node.from : node.to, node.to, Decoration4.replace({
|
|
812
|
+
widget: new ImageWidget(url)
|
|
813
|
+
}));
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
return builder.finish();
|
|
819
|
+
};
|
|
820
|
+
var ImageWidget = class extends WidgetType2 {
|
|
821
|
+
constructor(_url) {
|
|
822
|
+
super();
|
|
823
|
+
this._url = _url;
|
|
824
|
+
}
|
|
825
|
+
eq(other) {
|
|
826
|
+
return this._url === other?._url;
|
|
827
|
+
}
|
|
828
|
+
toDOM(view) {
|
|
829
|
+
const img = document.createElement("img");
|
|
830
|
+
img.setAttribute("src", this._url);
|
|
831
|
+
img.setAttribute("class", "cm-image");
|
|
832
|
+
return img;
|
|
833
|
+
}
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/link.ts
|
|
837
|
+
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
838
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField3 } from "@codemirror/state";
|
|
839
|
+
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
840
|
+
var link = (options = {}) => {
|
|
841
|
+
return StateField3.define({
|
|
842
|
+
create: (state) => update2(state, options),
|
|
843
|
+
update: (_, tr) => update2(tr.state, options),
|
|
844
|
+
provide: (field) => EditorView7.decorations.from(field)
|
|
845
|
+
});
|
|
846
|
+
};
|
|
847
|
+
var LinkButton = class extends WidgetType3 {
|
|
62
848
|
constructor(_pos, _url, _onAttach) {
|
|
63
849
|
super();
|
|
64
850
|
this._pos = _pos;
|
|
@@ -74,7 +860,7 @@ var LinkButton = class extends WidgetType {
|
|
|
74
860
|
return el;
|
|
75
861
|
}
|
|
76
862
|
};
|
|
77
|
-
var LinkText = class extends
|
|
863
|
+
var LinkText = class extends WidgetType3 {
|
|
78
864
|
constructor(_pos, _text, _url) {
|
|
79
865
|
super();
|
|
80
866
|
this._pos = _pos;
|
|
@@ -104,96 +890,68 @@ var LinkText = class extends WidgetType {
|
|
|
104
890
|
return link2;
|
|
105
891
|
}
|
|
106
892
|
};
|
|
107
|
-
var
|
|
108
|
-
const builder = new
|
|
893
|
+
var update2 = (state, options) => {
|
|
894
|
+
const builder = new RangeSetBuilder2();
|
|
109
895
|
const cursor = state.selection.main.head;
|
|
110
|
-
|
|
896
|
+
syntaxTree2(state).iterate({
|
|
111
897
|
enter: (node) => {
|
|
112
898
|
if (node.name === "Link") {
|
|
113
|
-
const
|
|
114
|
-
const text =
|
|
899
|
+
const marks2 = node.node.getChildren("LinkMark");
|
|
900
|
+
const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
|
|
115
901
|
const urlNode = node.node.getChild("URL");
|
|
116
902
|
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
117
|
-
if (
|
|
118
|
-
|
|
903
|
+
if (!url) {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
if (state.readOnly || cursor < node.from || cursor > node.to) {
|
|
907
|
+
builder.add(node.from, node.to, Decoration5.replace({
|
|
119
908
|
widget: new LinkText(node.from, text, options.link ? url : void 0)
|
|
120
909
|
}));
|
|
121
910
|
}
|
|
122
911
|
if (options.onRender) {
|
|
123
|
-
builder.add(node.to, node.to,
|
|
912
|
+
builder.add(node.to, node.to, Decoration5.replace({
|
|
124
913
|
widget: new LinkButton(node.from, url, options.onRender)
|
|
125
914
|
}));
|
|
126
915
|
}
|
|
916
|
+
return false;
|
|
127
917
|
}
|
|
128
|
-
return true;
|
|
129
918
|
}
|
|
130
919
|
});
|
|
131
920
|
return builder.finish();
|
|
132
921
|
};
|
|
133
|
-
var link = (options = {}) => {
|
|
134
|
-
return StateField.define({
|
|
135
|
-
create: (state) => update(state, options),
|
|
136
|
-
update: (_, tr) => update(tr.state, options),
|
|
137
|
-
provide: (field) => EditorView2.decorations.from(field)
|
|
138
|
-
});
|
|
139
|
-
};
|
|
140
922
|
|
|
141
923
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/listener.ts
|
|
142
|
-
import { StateField as
|
|
143
|
-
var
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
924
|
+
import { StateField as StateField4 } from "@codemirror/state";
|
|
925
|
+
var listener2 = ({ onChange }) => {
|
|
926
|
+
return StateField4.define({
|
|
927
|
+
create: () => null,
|
|
928
|
+
update: (_value, transaction) => {
|
|
929
|
+
if (transaction.docChanged && onChange) {
|
|
930
|
+
onChange(transaction.newDoc.toString());
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
148
933
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
});
|
|
934
|
+
});
|
|
935
|
+
};
|
|
152
936
|
|
|
153
937
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
|
|
154
938
|
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
155
|
-
import {
|
|
939
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
156
940
|
import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
|
|
157
|
-
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2,
|
|
941
|
+
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
158
942
|
import { languages } from "@codemirror/language-data";
|
|
159
|
-
import {
|
|
160
|
-
import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
|
|
943
|
+
import { searchKeymap } from "@codemirror/search";
|
|
161
944
|
import { EditorState } from "@codemirror/state";
|
|
162
945
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
163
|
-
import { crosshairCursor, drawSelection, dropCursor, EditorView as
|
|
946
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView8, keymap as keymap5, placeholder as placeholder2 } from "@codemirror/view";
|
|
164
947
|
|
|
165
948
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
|
|
166
949
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
167
950
|
import { HighlightStyle } from "@codemirror/language";
|
|
168
951
|
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
169
|
-
import
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
173
|
-
var heading = {
|
|
174
|
-
1: "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
175
|
-
2: "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
176
|
-
3: "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
177
|
-
4: "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
178
|
-
5: "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
179
|
-
6: "mbs-4 mbe-2 font-medium text-inherit no-underline"
|
|
180
|
-
};
|
|
181
|
-
var light = "text-neutral-200 dark:text-neutral-800";
|
|
182
|
-
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
183
|
-
var bold = "font-bold";
|
|
184
|
-
var italic = "italic";
|
|
185
|
-
var strikethrough = "line-through";
|
|
186
|
-
var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
|
|
187
|
-
var codeMark = "font-mono text-primary-500";
|
|
188
|
-
var inlineUrl = mx(code, "px-1");
|
|
189
|
-
var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
|
|
190
|
-
var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-500/50";
|
|
191
|
-
|
|
192
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
193
|
-
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
194
|
-
var tokens = tailwindConfig({}).theme;
|
|
195
|
-
|
|
196
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
|
|
952
|
+
import { Table } from "@lezer/markdown";
|
|
953
|
+
import get2 from "lodash.get";
|
|
954
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
197
955
|
var markdownTags = {
|
|
198
956
|
Blockquote: Tag.define(),
|
|
199
957
|
CodeMark: Tag.define(),
|
|
@@ -206,179 +964,201 @@ var markdownTags = {
|
|
|
206
964
|
LinkReference: Tag.define(),
|
|
207
965
|
ListMark: Tag.define(),
|
|
208
966
|
QuoteMark: Tag.define(),
|
|
209
|
-
URL: Tag.define()
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
props: [
|
|
213
|
-
styleTags(markdownTags)
|
|
214
|
-
]
|
|
967
|
+
URL: Tag.define(),
|
|
968
|
+
// Custom.
|
|
969
|
+
TableCell: Tag.define()
|
|
215
970
|
};
|
|
216
|
-
|
|
217
|
-
{
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
tags.character,
|
|
223
|
-
tags.propertyName,
|
|
224
|
-
tags.macroName,
|
|
225
|
-
tags.color,
|
|
226
|
-
tags.constant(tags.name),
|
|
227
|
-
tags.standard(tags.name),
|
|
228
|
-
tags.definition(tags.name),
|
|
229
|
-
tags.separator,
|
|
230
|
-
tags.typeName,
|
|
231
|
-
tags.className,
|
|
232
|
-
tags.number,
|
|
233
|
-
tags.changed,
|
|
234
|
-
tags.annotation,
|
|
235
|
-
tags.modifier,
|
|
236
|
-
tags.self,
|
|
237
|
-
tags.namespace,
|
|
238
|
-
tags.operator,
|
|
239
|
-
tags.operatorKeyword,
|
|
240
|
-
tags.escape,
|
|
241
|
-
tags.regexp,
|
|
242
|
-
tags.special(tags.string),
|
|
243
|
-
tags.meta,
|
|
244
|
-
tags.comment,
|
|
245
|
-
tags.atom,
|
|
246
|
-
tags.bool,
|
|
247
|
-
tags.special(tags.variableName),
|
|
248
|
-
tags.processingInstruction,
|
|
249
|
-
tags.string,
|
|
250
|
-
tags.inserted,
|
|
251
|
-
tags.invalid
|
|
252
|
-
],
|
|
253
|
-
color: "inherit !important"
|
|
254
|
-
},
|
|
255
|
-
// Markdown marks.
|
|
256
|
-
{
|
|
257
|
-
tag: [
|
|
258
|
-
tags.meta,
|
|
259
|
-
tags.processingInstruction,
|
|
260
|
-
markdownTags.CodeMark,
|
|
261
|
-
markdownTags.EmphasisMark,
|
|
262
|
-
markdownTags.HeaderMark,
|
|
263
|
-
markdownTags.LinkLabel,
|
|
264
|
-
markdownTags.LinkReference,
|
|
265
|
-
markdownTags.ListMark,
|
|
266
|
-
markdownTags.QuoteMark
|
|
267
|
-
],
|
|
268
|
-
class: mark
|
|
269
|
-
},
|
|
270
|
-
// Headings.
|
|
271
|
-
{
|
|
272
|
-
tag: tags.heading1,
|
|
273
|
-
class: heading[1]
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
tag: tags.heading2,
|
|
277
|
-
class: heading[2]
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
tag: tags.heading3,
|
|
281
|
-
class: heading[3]
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
tag: tags.heading4,
|
|
285
|
-
class: heading[4]
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
tag: tags.heading5,
|
|
289
|
-
class: heading[5]
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
tag: tags.heading6,
|
|
293
|
-
class: heading[6]
|
|
294
|
-
},
|
|
295
|
-
// Emphasis.
|
|
296
|
-
{
|
|
297
|
-
tag: tags.emphasis,
|
|
298
|
-
class: italic
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
tag: tags.strong,
|
|
302
|
-
class: bold
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
tag: tags.strikethrough,
|
|
306
|
-
class: strikethrough
|
|
307
|
-
},
|
|
308
|
-
// Naked URLs.
|
|
309
|
-
{
|
|
310
|
-
tag: [
|
|
311
|
-
markdownTags.URL
|
|
312
|
-
],
|
|
313
|
-
class: inlineUrl
|
|
314
|
-
},
|
|
315
|
-
// E.g., code block language (after ```).
|
|
316
|
-
{
|
|
317
|
-
tag: [
|
|
318
|
-
tags.function(tags.variableName),
|
|
319
|
-
tags.labelName
|
|
320
|
-
],
|
|
321
|
-
class: codeMark
|
|
322
|
-
},
|
|
323
|
-
// The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
324
|
-
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
325
|
-
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
326
|
-
// the code, but all other CSS properties will be inherited.
|
|
327
|
-
{
|
|
328
|
-
tag: [
|
|
329
|
-
markdownTags.CodeText,
|
|
330
|
-
markdownTags.InlineCode
|
|
331
|
-
],
|
|
332
|
-
class: code
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
tag: [
|
|
336
|
-
markdownTags.QuoteMark
|
|
337
|
-
],
|
|
338
|
-
class: blockquote
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
tag: [
|
|
342
|
-
markdownTags.HorizontalRule
|
|
343
|
-
],
|
|
344
|
-
class: horizontalRule
|
|
345
|
-
}
|
|
346
|
-
], {
|
|
347
|
-
scope: markdownLanguage,
|
|
348
|
-
all: {
|
|
349
|
-
fontFamily: get(tokens, "fontFamily.body", []).join(",")
|
|
971
|
+
Table.defineNodes?.forEach((node) => {
|
|
972
|
+
switch (node?.name) {
|
|
973
|
+
case "TableCell": {
|
|
974
|
+
node.style = markdownTags.TableCell;
|
|
975
|
+
break;
|
|
976
|
+
}
|
|
350
977
|
}
|
|
351
978
|
});
|
|
979
|
+
var markdownTagsExtensions = [
|
|
980
|
+
Table,
|
|
981
|
+
{
|
|
982
|
+
props: [
|
|
983
|
+
styleTags(markdownTags)
|
|
984
|
+
]
|
|
985
|
+
}
|
|
986
|
+
];
|
|
987
|
+
var markdownHighlightStyle = (readonly) => {
|
|
988
|
+
return HighlightStyle.define([
|
|
989
|
+
{
|
|
990
|
+
tag: [
|
|
991
|
+
tags.keyword,
|
|
992
|
+
tags.name,
|
|
993
|
+
tags.deleted,
|
|
994
|
+
tags.character,
|
|
995
|
+
tags.propertyName,
|
|
996
|
+
tags.macroName,
|
|
997
|
+
tags.color,
|
|
998
|
+
tags.constant(tags.name),
|
|
999
|
+
tags.standard(tags.name),
|
|
1000
|
+
tags.definition(tags.name),
|
|
1001
|
+
tags.separator,
|
|
1002
|
+
tags.typeName,
|
|
1003
|
+
tags.className,
|
|
1004
|
+
tags.number,
|
|
1005
|
+
tags.changed,
|
|
1006
|
+
tags.annotation,
|
|
1007
|
+
tags.modifier,
|
|
1008
|
+
tags.self,
|
|
1009
|
+
tags.namespace,
|
|
1010
|
+
tags.operator,
|
|
1011
|
+
tags.operatorKeyword,
|
|
1012
|
+
tags.escape,
|
|
1013
|
+
tags.regexp,
|
|
1014
|
+
tags.special(tags.string),
|
|
1015
|
+
tags.meta,
|
|
1016
|
+
tags.comment,
|
|
1017
|
+
tags.atom,
|
|
1018
|
+
tags.bool,
|
|
1019
|
+
tags.special(tags.variableName),
|
|
1020
|
+
tags.processingInstruction,
|
|
1021
|
+
tags.string,
|
|
1022
|
+
tags.inserted,
|
|
1023
|
+
tags.invalid
|
|
1024
|
+
],
|
|
1025
|
+
color: "inherit !important"
|
|
1026
|
+
},
|
|
1027
|
+
// Markdown marks.
|
|
1028
|
+
{
|
|
1029
|
+
tag: [
|
|
1030
|
+
tags.meta,
|
|
1031
|
+
tags.processingInstruction,
|
|
1032
|
+
markdownTags.LinkLabel,
|
|
1033
|
+
markdownTags.LinkReference,
|
|
1034
|
+
markdownTags.ListMark
|
|
1035
|
+
],
|
|
1036
|
+
class: mark
|
|
1037
|
+
},
|
|
1038
|
+
// Markdown marks.
|
|
1039
|
+
{
|
|
1040
|
+
tag: [
|
|
1041
|
+
markdownTags.CodeMark,
|
|
1042
|
+
markdownTags.HeaderMark,
|
|
1043
|
+
markdownTags.QuoteMark,
|
|
1044
|
+
markdownTags.EmphasisMark
|
|
1045
|
+
],
|
|
1046
|
+
class: readonly ? "hidden" : mark
|
|
1047
|
+
},
|
|
1048
|
+
// E.g., code block language (after ```).
|
|
1049
|
+
{
|
|
1050
|
+
tag: [
|
|
1051
|
+
tags.function(tags.variableName),
|
|
1052
|
+
tags.labelName
|
|
1053
|
+
],
|
|
1054
|
+
class: readonly ? "hidden" : codeMark
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
tag: [
|
|
1058
|
+
tags.monospace
|
|
1059
|
+
],
|
|
1060
|
+
class: "font-mono"
|
|
1061
|
+
},
|
|
1062
|
+
// Headings.
|
|
1063
|
+
{
|
|
1064
|
+
tag: tags.heading1,
|
|
1065
|
+
class: heading(1, readonly)
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
tag: tags.heading2,
|
|
1069
|
+
class: heading(2, readonly)
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
tag: tags.heading3,
|
|
1073
|
+
class: heading(3, readonly)
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
tag: tags.heading4,
|
|
1077
|
+
class: heading(4, readonly)
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
tag: tags.heading5,
|
|
1081
|
+
class: heading(5, readonly)
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
tag: tags.heading6,
|
|
1085
|
+
class: heading(6, readonly)
|
|
1086
|
+
},
|
|
1087
|
+
// Emphasis.
|
|
1088
|
+
{
|
|
1089
|
+
tag: tags.emphasis,
|
|
1090
|
+
class: italic
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
tag: tags.strong,
|
|
1094
|
+
class: bold
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
tag: tags.strikethrough,
|
|
1098
|
+
class: strikethrough
|
|
1099
|
+
},
|
|
1100
|
+
// Naked URLs.
|
|
1101
|
+
{
|
|
1102
|
+
tag: [
|
|
1103
|
+
markdownTags.URL
|
|
1104
|
+
],
|
|
1105
|
+
class: inlineUrl
|
|
1106
|
+
},
|
|
1107
|
+
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
1108
|
+
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
1109
|
+
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
1110
|
+
// the code, but all other CSS properties will be inherited.
|
|
1111
|
+
// IMPORTANT: Therefore, the fenced code block will use the base editor font.
|
|
1112
|
+
{
|
|
1113
|
+
tag: [
|
|
1114
|
+
markdownTags.CodeText,
|
|
1115
|
+
markdownTags.InlineCode
|
|
1116
|
+
],
|
|
1117
|
+
class: code
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
tag: [
|
|
1121
|
+
markdownTags.QuoteMark
|
|
1122
|
+
],
|
|
1123
|
+
class: blockquote
|
|
1124
|
+
},
|
|
1125
|
+
// TODO(burdon): Replace with extension.
|
|
1126
|
+
{
|
|
1127
|
+
tag: [
|
|
1128
|
+
markdownTags.HorizontalRule
|
|
1129
|
+
],
|
|
1130
|
+
class: mx3(horizontalRule, readonly && "-indent-[100rem]")
|
|
1131
|
+
},
|
|
1132
|
+
// TODO(burdon): Only if being edited.
|
|
1133
|
+
{
|
|
1134
|
+
tag: [
|
|
1135
|
+
markdownTags.TableCell
|
|
1136
|
+
],
|
|
1137
|
+
class: "font-mono"
|
|
1138
|
+
}
|
|
1139
|
+
], {
|
|
1140
|
+
scope: markdownLanguage,
|
|
1141
|
+
all: {
|
|
1142
|
+
fontFamily: get2(tokens, "fontFamily.body", []).join(",")
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
};
|
|
352
1146
|
|
|
353
1147
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
|
|
354
|
-
var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
1148
|
+
var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
355
1149
|
return [
|
|
1150
|
+
EditorState.allowMultipleSelections.of(true),
|
|
1151
|
+
EditorState.tabSize.of(2),
|
|
1152
|
+
EditorView8.lineWrapping,
|
|
1153
|
+
customKeymap(),
|
|
356
1154
|
bracketMatching2(),
|
|
357
1155
|
closeBrackets2(),
|
|
358
|
-
_placeholder && placeholder2(_placeholder),
|
|
359
|
-
EditorState.allowMultipleSelections.of(true),
|
|
360
|
-
EditorView3.lineWrapping,
|
|
361
|
-
// autocompletion(),
|
|
362
1156
|
crosshairCursor(),
|
|
363
1157
|
dropCursor(),
|
|
364
|
-
|
|
365
|
-
highlightActiveLine(),
|
|
366
|
-
highlightActiveLineGutter(),
|
|
367
|
-
highlightSelectionMatches(),
|
|
368
|
-
highlightSpecialChars(),
|
|
1158
|
+
drawSelection2(),
|
|
369
1159
|
history(),
|
|
370
1160
|
indentOnInput(),
|
|
371
|
-
|
|
372
|
-
keymap2.of([
|
|
373
|
-
...closeBracketsKeymap,
|
|
374
|
-
// ...completionKeymap,
|
|
375
|
-
...defaultKeymap,
|
|
376
|
-
...foldKeymap,
|
|
377
|
-
...historyKeymap,
|
|
378
|
-
...lintKeymap,
|
|
379
|
-
...searchKeymap,
|
|
380
|
-
indentWithTab
|
|
381
|
-
]),
|
|
1161
|
+
_placeholder && placeholder2(_placeholder),
|
|
382
1162
|
// Main extension.
|
|
383
1163
|
// https://github.com/codemirror/lang-markdown
|
|
384
1164
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -393,102 +1173,231 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
393
1173
|
codeLanguages: languages,
|
|
394
1174
|
// Parser extensions.
|
|
395
1175
|
extensions: [
|
|
396
|
-
// GFM
|
|
397
|
-
|
|
1176
|
+
// GFM provided by default.
|
|
1177
|
+
markdownTagsExtensions
|
|
398
1178
|
]
|
|
399
1179
|
}),
|
|
1180
|
+
// https://github.com/codemirror/theme-one-dark
|
|
1181
|
+
themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2),
|
|
400
1182
|
// Custom styles.
|
|
401
|
-
syntaxHighlighting2(markdownHighlightStyle)
|
|
402
|
-
// TODO(thure): All but one rule here apply to both themes; rename or refactor.
|
|
403
|
-
themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2)
|
|
1183
|
+
syntaxHighlighting2(markdownHighlightStyle(readonly))
|
|
404
1184
|
].filter(Boolean);
|
|
405
1185
|
};
|
|
1186
|
+
var customKeymap = () => keymap5.of([
|
|
1187
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1188
|
+
indentWithTab,
|
|
1189
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1190
|
+
...standardKeymap,
|
|
1191
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
1192
|
+
...historyKeymap,
|
|
1193
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
1194
|
+
...closeBracketsKeymap,
|
|
1195
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
1196
|
+
...searchKeymap
|
|
1197
|
+
]);
|
|
1198
|
+
|
|
1199
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/mention.ts
|
|
1200
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
1201
|
+
var mention = ({ onSearch }) => {
|
|
1202
|
+
return autocompletion2({
|
|
1203
|
+
closeOnBlur: false,
|
|
1204
|
+
override: [
|
|
1205
|
+
(context) => {
|
|
1206
|
+
const match = context.matchBefore(/@(\w+)?/);
|
|
1207
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
1208
|
+
return null;
|
|
1209
|
+
}
|
|
1210
|
+
console.log(match);
|
|
1211
|
+
return {
|
|
1212
|
+
from: match.from,
|
|
1213
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
|
1214
|
+
label: `@${value}`
|
|
1215
|
+
}))
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
]
|
|
1219
|
+
});
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/table.ts
|
|
1223
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1224
|
+
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
|
|
1225
|
+
import { Decoration as Decoration6, EditorView as EditorView9, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1226
|
+
var table = (options = {}) => {
|
|
1227
|
+
return StateField5.define({
|
|
1228
|
+
create: (state) => update3(state, options),
|
|
1229
|
+
update: (_, tr) => update3(tr.state, options),
|
|
1230
|
+
provide: (field) => EditorView9.decorations.from(field)
|
|
1231
|
+
});
|
|
1232
|
+
};
|
|
1233
|
+
var update3 = (state, options) => {
|
|
1234
|
+
const builder = new RangeSetBuilder3();
|
|
1235
|
+
const cursor = state.selection.main.head;
|
|
1236
|
+
const tables = [];
|
|
1237
|
+
const getTable = () => tables[tables.length - 1];
|
|
1238
|
+
const getRow = () => {
|
|
1239
|
+
const table2 = getTable();
|
|
1240
|
+
return table2.rows?.[table2.rows.length - 1];
|
|
1241
|
+
};
|
|
1242
|
+
syntaxTree3(state).iterate({
|
|
1243
|
+
enter: (node) => {
|
|
1244
|
+
switch (node.name) {
|
|
1245
|
+
case "Table": {
|
|
1246
|
+
tables.push({
|
|
1247
|
+
from: node.from,
|
|
1248
|
+
to: node.to
|
|
1249
|
+
});
|
|
1250
|
+
break;
|
|
1251
|
+
}
|
|
1252
|
+
case "TableHeader": {
|
|
1253
|
+
getTable().header = [];
|
|
1254
|
+
break;
|
|
1255
|
+
}
|
|
1256
|
+
case "TableRow": {
|
|
1257
|
+
(getTable().rows ??= []).push([]);
|
|
1258
|
+
break;
|
|
1259
|
+
}
|
|
1260
|
+
case "TableCell": {
|
|
1261
|
+
const row = getRow();
|
|
1262
|
+
if (row) {
|
|
1263
|
+
row.push(state.sliceDoc(node.from, node.to));
|
|
1264
|
+
} else {
|
|
1265
|
+
getTable().header?.push(state.sliceDoc(node.from, node.to));
|
|
1266
|
+
}
|
|
1267
|
+
break;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
tables.forEach((table2) => {
|
|
1273
|
+
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
1274
|
+
hide && builder.add(table2.from, table2.to, Decoration6.replace({
|
|
1275
|
+
widget: new TableWidget(table2)
|
|
1276
|
+
}));
|
|
1277
|
+
builder.add(table2.from, table2.to, Decoration6.mark({
|
|
1278
|
+
class: "cm-table"
|
|
1279
|
+
}));
|
|
1280
|
+
});
|
|
1281
|
+
return builder.finish();
|
|
1282
|
+
};
|
|
1283
|
+
var TableWidget = class extends WidgetType4 {
|
|
1284
|
+
constructor(_table) {
|
|
1285
|
+
super();
|
|
1286
|
+
this._table = _table;
|
|
1287
|
+
}
|
|
1288
|
+
eq(other) {
|
|
1289
|
+
return this._table.from === other?._table?.from;
|
|
1290
|
+
}
|
|
1291
|
+
toDOM(view) {
|
|
1292
|
+
const table2 = document.createElement("table");
|
|
1293
|
+
{
|
|
1294
|
+
const header = table2.appendChild(document.createElement("thead"));
|
|
1295
|
+
const tr = header.appendChild(document.createElement("tr"));
|
|
1296
|
+
this._table.header?.forEach((cell) => {
|
|
1297
|
+
const th = document.createElement("th");
|
|
1298
|
+
th.setAttribute("class", "cm-table-head");
|
|
1299
|
+
tr.appendChild(th).textContent = cell;
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
{
|
|
1303
|
+
const body = table2.appendChild(document.createElement("tbody"));
|
|
1304
|
+
this._table.rows?.forEach((row) => {
|
|
1305
|
+
const tr = body.appendChild(document.createElement("tr"));
|
|
1306
|
+
row.forEach((cell) => {
|
|
1307
|
+
const td = document.createElement("td");
|
|
1308
|
+
td.setAttribute("class", "cm-table-cell");
|
|
1309
|
+
tr.appendChild(td).textContent = cell;
|
|
1310
|
+
});
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
return table2;
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
406
1316
|
|
|
407
1317
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/tasklist.ts
|
|
408
|
-
import {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
1318
|
+
import { EditorView as EditorView10, Decoration as Decoration7, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
|
|
1319
|
+
var styles4 = EditorView10.baseTheme({
|
|
1320
|
+
"& .cm-task-item": {
|
|
1321
|
+
paddingLeft: "4px",
|
|
1322
|
+
paddingRight: "8px"
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
var CheckboxWidget = class extends WidgetType5 {
|
|
1326
|
+
constructor(_pos, _checked, _indent, _onCheck) {
|
|
413
1327
|
super();
|
|
414
1328
|
this._pos = _pos;
|
|
415
|
-
this._getCursor = _getCursor;
|
|
416
1329
|
this._checked = _checked;
|
|
1330
|
+
this._indent = _indent;
|
|
1331
|
+
this._onCheck = _onCheck;
|
|
417
1332
|
}
|
|
418
1333
|
eq(other) {
|
|
419
|
-
return this._pos === other._pos && this._checked === other._checked;
|
|
1334
|
+
return this._pos === other._pos && this._checked === other._checked && this._indent === other._indent;
|
|
420
1335
|
}
|
|
421
1336
|
toDOM(view) {
|
|
422
1337
|
const wrap = document.createElement("span");
|
|
423
|
-
wrap.setAttribute("aria-hidden", "true");
|
|
424
1338
|
wrap.className = "cm-task-item";
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
});
|
|
441
|
-
return true;
|
|
442
|
-
};
|
|
1339
|
+
wrap.setAttribute("aria-hidden", "true");
|
|
1340
|
+
wrap.style.setProperty("margin-left", this._indent * 24 + "px");
|
|
1341
|
+
const input = wrap.appendChild(document.createElement("input"));
|
|
1342
|
+
input.type = "checkbox";
|
|
1343
|
+
input.checked = this._checked;
|
|
1344
|
+
if (!this._onCheck) {
|
|
1345
|
+
input.setAttribute("disabled", "true");
|
|
1346
|
+
}
|
|
1347
|
+
if (this._onCheck) {
|
|
1348
|
+
input.onchange = (event) => {
|
|
1349
|
+
this._onCheck?.(event.target.checked);
|
|
1350
|
+
return true;
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
443
1353
|
return wrap;
|
|
444
1354
|
}
|
|
445
|
-
// TODO(burdon): Remove listener?
|
|
446
|
-
// override destroy() {
|
|
447
|
-
// console.log('destroy', this._pos);
|
|
448
|
-
// }
|
|
449
1355
|
ignoreEvent() {
|
|
450
1356
|
return false;
|
|
451
1357
|
}
|
|
452
1358
|
};
|
|
453
|
-
var
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
1359
|
+
var tasklist = (options = {}) => {
|
|
1360
|
+
const taskMatcher = new MatchDecorator2({
|
|
1361
|
+
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
1362
|
+
decoration: (match, view, pos) => {
|
|
1363
|
+
const indent = Math.floor(match[1].length / 2);
|
|
1364
|
+
const checked = match[2] === "x" || match[2] === "X";
|
|
1365
|
+
return Decoration7.replace({
|
|
1366
|
+
widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
|
|
1367
|
+
const idx = pos + match[0].indexOf("[") + 1;
|
|
1368
|
+
view.dispatch({
|
|
1369
|
+
changes: {
|
|
1370
|
+
from: idx,
|
|
1371
|
+
to: idx + 1,
|
|
1372
|
+
insert: checked2 ? "x" : " "
|
|
1373
|
+
},
|
|
1374
|
+
// TODO(burdon): Restore cursor position? More useful to move to end of line (can indent).
|
|
1375
|
+
selection: {
|
|
1376
|
+
anchor: idx + 3
|
|
1377
|
+
}
|
|
1378
|
+
});
|
|
1379
|
+
})
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
460
1382
|
});
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
return builder.finish();
|
|
473
|
-
};
|
|
474
|
-
return [
|
|
475
|
-
listener2,
|
|
476
|
-
StateField3.define({
|
|
477
|
-
create: (state) => checkbox(state),
|
|
478
|
-
update: (_, tr) => checkbox(tr.state),
|
|
479
|
-
provide: (field) => EditorView4.decorations.from(field)
|
|
1383
|
+
const tasks = ViewPlugin3.fromClass(class {
|
|
1384
|
+
constructor(view) {
|
|
1385
|
+
this.tasks = taskMatcher.createDeco(view);
|
|
1386
|
+
}
|
|
1387
|
+
update(update4) {
|
|
1388
|
+
this.tasks = taskMatcher.updateDeco(update4, this.tasks);
|
|
1389
|
+
}
|
|
1390
|
+
}, {
|
|
1391
|
+
decorations: (value) => value.tasks,
|
|
1392
|
+
provide: (plugin) => EditorView10.atomicRanges.of((view) => {
|
|
1393
|
+
return view.plugin(plugin)?.tasks || Decoration7.none;
|
|
480
1394
|
})
|
|
1395
|
+
});
|
|
1396
|
+
return [
|
|
1397
|
+
tasks,
|
|
1398
|
+
styles4
|
|
481
1399
|
];
|
|
482
1400
|
};
|
|
483
|
-
var styles = EditorView4.baseTheme({
|
|
484
|
-
"& .cm-task-item": {
|
|
485
|
-
padding: "0 4px"
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
var tasklist = () => [
|
|
489
|
-
statefield(),
|
|
490
|
-
styles
|
|
491
|
-
];
|
|
492
1401
|
|
|
493
1402
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/tooltip.tsx
|
|
494
1403
|
import { hoverTooltip } from "@codemirror/view";
|
|
@@ -535,7 +1444,7 @@ var tooltip = ({ onHover, regexp = markdownLinkRegexp }) => hoverTooltip((view,
|
|
|
535
1444
|
});
|
|
536
1445
|
|
|
537
1446
|
// packages/ui/react-ui-editor/src/components/TextEditor/themes/default.ts
|
|
538
|
-
import
|
|
1447
|
+
import get3 from "lodash.get";
|
|
539
1448
|
var defaultTheme = {
|
|
540
1449
|
//
|
|
541
1450
|
// Main layout:
|
|
@@ -560,20 +1469,20 @@ var defaultTheme = {
|
|
|
560
1469
|
fontSize: "16px"
|
|
561
1470
|
},
|
|
562
1471
|
"&light .cm-content": {
|
|
563
|
-
color:
|
|
1472
|
+
color: get3(tokens, "extend.colors.neutral.900", "black"),
|
|
564
1473
|
caretColor: "black"
|
|
565
1474
|
},
|
|
566
1475
|
"&dark .cm-content": {
|
|
567
|
-
color:
|
|
1476
|
+
color: get3(tokens, "extend.colors.neutral.100", "white"),
|
|
568
1477
|
caretColor: "white"
|
|
569
1478
|
},
|
|
570
1479
|
//
|
|
571
1480
|
// Cursor
|
|
572
1481
|
//
|
|
573
|
-
"&light .cm-cursor": {
|
|
1482
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
574
1483
|
borderLeft: "2px solid black"
|
|
575
1484
|
},
|
|
576
|
-
"&dark .cm-cursor": {
|
|
1485
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
577
1486
|
borderLeft: "2px solid white"
|
|
578
1487
|
},
|
|
579
1488
|
"& .cm-placeholder": {
|
|
@@ -593,16 +1502,16 @@ var defaultTheme = {
|
|
|
593
1502
|
// selection
|
|
594
1503
|
//
|
|
595
1504
|
"&light .cm-selectionBackground, &light.cm-focused .cm-selectionBackground": {
|
|
596
|
-
background:
|
|
1505
|
+
background: get3(tokens, "extend.colors.primary.150", "#00ffff")
|
|
597
1506
|
},
|
|
598
1507
|
"&dark .cm-selectionBackground, &dark.cm-focused .cm-selectionBackground": {
|
|
599
|
-
background:
|
|
1508
|
+
background: get3(tokens, "extend.colors.primary.850", "#00ffff")
|
|
600
1509
|
},
|
|
601
1510
|
"&light .cm-selectionMatch": {
|
|
602
|
-
background:
|
|
1511
|
+
background: get3(tokens, "extend.colors.primary.250", "#00ffff") + "44"
|
|
603
1512
|
},
|
|
604
1513
|
"&dark .cm-selectionMatch": {
|
|
605
|
-
background:
|
|
1514
|
+
background: get3(tokens, "extend.colors.primary.600", "#00ffff") + "44"
|
|
606
1515
|
},
|
|
607
1516
|
//
|
|
608
1517
|
// collaboration
|
|
@@ -635,12 +1544,12 @@ var defaultTheme = {
|
|
|
635
1544
|
// link
|
|
636
1545
|
//
|
|
637
1546
|
"& .cm-link": {
|
|
638
|
-
color:
|
|
1547
|
+
color: get3(tokens, "extend.colors.primary.500"),
|
|
639
1548
|
textDecorationLine: "underline",
|
|
640
1549
|
textDecorationThickness: "1px",
|
|
641
1550
|
textUnderlineOffset: "2px",
|
|
642
1551
|
borderRadius: ".125rem",
|
|
643
|
-
fontFamily:
|
|
1552
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
644
1553
|
},
|
|
645
1554
|
//
|
|
646
1555
|
// tooltip
|
|
@@ -648,14 +1557,61 @@ var defaultTheme = {
|
|
|
648
1557
|
"& .cm-tooltip": {
|
|
649
1558
|
border: "none"
|
|
650
1559
|
},
|
|
651
|
-
|
|
652
|
-
//
|
|
1560
|
+
"& .cm-tooltip-below": {},
|
|
1561
|
+
//
|
|
1562
|
+
// autocomplete
|
|
1563
|
+
//
|
|
1564
|
+
"& .cm-tooltip-autocomplete": {
|
|
1565
|
+
marginTop: "4px",
|
|
1566
|
+
marginLeft: "-3px"
|
|
1567
|
+
},
|
|
1568
|
+
"& .cm-tooltip-autocomplete ul li": {},
|
|
1569
|
+
"& .cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
1570
|
+
"& .cm-completionIcon": {
|
|
1571
|
+
display: "none"
|
|
1572
|
+
},
|
|
1573
|
+
"& .cm-completionLabel": {
|
|
1574
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1575
|
+
},
|
|
1576
|
+
"& .cm-completionMatchedText": {
|
|
1577
|
+
textDecoration: "none"
|
|
1578
|
+
},
|
|
1579
|
+
//
|
|
1580
|
+
// widgets
|
|
1581
|
+
//
|
|
1582
|
+
"& .cm-widgetBuffer": {
|
|
1583
|
+
display: "none",
|
|
1584
|
+
height: 0
|
|
1585
|
+
},
|
|
1586
|
+
//
|
|
1587
|
+
// table
|
|
1588
|
+
//
|
|
1589
|
+
"& .cm-table *": {
|
|
1590
|
+
fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
1591
|
+
textDecoration: "none !important"
|
|
1592
|
+
},
|
|
1593
|
+
"& .cm-table-head": {
|
|
1594
|
+
padding: "2px 16px 2px 0px",
|
|
1595
|
+
borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
|
|
1596
|
+
fontWeight: 100,
|
|
1597
|
+
textAlign: "left",
|
|
1598
|
+
color: get3(tokens, "extend.colors.neutral.500")
|
|
1599
|
+
},
|
|
1600
|
+
"& .cm-table-cell": {
|
|
1601
|
+
padding: "2px 16px 2px 0px"
|
|
1602
|
+
},
|
|
1603
|
+
//
|
|
1604
|
+
// image
|
|
1605
|
+
//
|
|
1606
|
+
"& .cm-image": {
|
|
1607
|
+
margin: "0.5rem 0"
|
|
1608
|
+
},
|
|
653
1609
|
//
|
|
654
1610
|
// font size
|
|
655
1611
|
// TODO(thure): This appears to be the best or only way to set selection caret heights, but it's far more verbose than it needs to be.
|
|
656
1612
|
//
|
|
657
|
-
...Object.keys(
|
|
658
|
-
const height =
|
|
1613
|
+
...Object.keys(get3(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
|
|
1614
|
+
const height = get3(tokens, [
|
|
659
1615
|
"extend",
|
|
660
1616
|
"fontSize",
|
|
661
1617
|
fontSize,
|
|
@@ -672,40 +1628,99 @@ var defaultTheme = {
|
|
|
672
1628
|
height
|
|
673
1629
|
};
|
|
674
1630
|
return acc;
|
|
675
|
-
}, {})
|
|
1631
|
+
}, {}),
|
|
1632
|
+
/**
|
|
1633
|
+
* Panels
|
|
1634
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
1635
|
+
*
|
|
1636
|
+
* Find/replace panel.
|
|
1637
|
+
* <div class="cm-announced">...</div>
|
|
1638
|
+
* <div class="cm-scroller">...</div>
|
|
1639
|
+
* <div class="cm-panels cm-panels-bottom">
|
|
1640
|
+
* <div class="cm-search cm-panel">
|
|
1641
|
+
* <input class="cm-textfield" />
|
|
1642
|
+
* <button class="cm-button">...</button>
|
|
1643
|
+
* <label><input type="checkbox" />...</label>
|
|
1644
|
+
* </div>
|
|
1645
|
+
* </div
|
|
1646
|
+
*/
|
|
1647
|
+
"& .cm-panels": {
|
|
1648
|
+
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`,
|
|
1649
|
+
borderBottom: "none"
|
|
1650
|
+
},
|
|
1651
|
+
"& .cm-panel": {
|
|
1652
|
+
background: get3(tokens, "extend.colors.neutral.50"),
|
|
1653
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1654
|
+
},
|
|
1655
|
+
"& .cm-button": {
|
|
1656
|
+
margin: "4px",
|
|
1657
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
1658
|
+
background: get3(tokens, "extend.colors.neutral.100"),
|
|
1659
|
+
border: "none"
|
|
1660
|
+
},
|
|
1661
|
+
"& .cm-searchMatch": {
|
|
1662
|
+
backgroundColor: get3(tokens, "extend.colors.yellow.100")
|
|
1663
|
+
},
|
|
1664
|
+
"& .cm-searchMatch.cm-searchMatch-selected": {
|
|
1665
|
+
backgroundColor: get3(tokens, "extend.colors.primary.100")
|
|
1666
|
+
}
|
|
676
1667
|
};
|
|
677
1668
|
var textTheme = {
|
|
678
1669
|
"& .cm-scroller": {
|
|
679
|
-
fontFamily:
|
|
1670
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1671
|
+
},
|
|
1672
|
+
"& .cm-placeholder": {
|
|
1673
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1676
|
+
var markdownTheme = {
|
|
1677
|
+
// NOTE: Must leave base font family as is (i.e., monospace) due to fenced code blocks.
|
|
1678
|
+
"& .cm-placeholder": {
|
|
1679
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
680
1680
|
}
|
|
681
1681
|
};
|
|
682
1682
|
var codeTheme = {
|
|
683
1683
|
"& .cm-scroller": {
|
|
684
|
-
fontFamily:
|
|
1684
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
1685
|
+
},
|
|
1686
|
+
"& .cm-placeholder": {
|
|
1687
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
685
1688
|
}
|
|
686
1689
|
};
|
|
687
1690
|
|
|
688
1691
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
689
1692
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
690
|
-
import { EditorView as
|
|
1693
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
691
1694
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
692
1695
|
import { vim } from "@replit/codemirror-vim";
|
|
693
|
-
import
|
|
694
|
-
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
|
|
1696
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
1697
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useState } from "react";
|
|
695
1698
|
import { generateName } from "@dxos/display-name";
|
|
696
1699
|
import { useThemeContext } from "@dxos/react-ui";
|
|
697
|
-
import { getColorForValue, inputSurface, mx as
|
|
1700
|
+
import { getColorForValue, inputSurface, mx as mx4 } from "@dxos/react-ui-theme";
|
|
698
1701
|
var EditorModes = [
|
|
699
1702
|
"default",
|
|
700
1703
|
"vim"
|
|
701
1704
|
];
|
|
702
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots = defaultSlots
|
|
1705
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode, extensions = [], slots = defaultSlots }, forwardedRef) => {
|
|
703
1706
|
const { themeMode } = useThemeContext();
|
|
704
1707
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
705
1708
|
tabBehavior: "limited"
|
|
706
1709
|
});
|
|
1710
|
+
const [root, setRoot] = useState(null);
|
|
1711
|
+
const [state, setState] = useState();
|
|
1712
|
+
const [view, setView] = useState();
|
|
1713
|
+
useImperativeHandle(forwardedRef, () => ({
|
|
1714
|
+
root,
|
|
1715
|
+
state,
|
|
1716
|
+
view
|
|
1717
|
+
}), [
|
|
1718
|
+
view,
|
|
1719
|
+
state,
|
|
1720
|
+
root
|
|
1721
|
+
]);
|
|
707
1722
|
const { awareness, peer } = model;
|
|
708
|
-
|
|
1723
|
+
useEffect2(() => {
|
|
709
1724
|
if (awareness && peer) {
|
|
710
1725
|
awareness.setLocalStateField("user", {
|
|
711
1726
|
name: peer.name ?? generateName(peer.id),
|
|
@@ -725,32 +1740,22 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
725
1740
|
peer,
|
|
726
1741
|
themeMode
|
|
727
1742
|
]);
|
|
728
|
-
|
|
729
|
-
const [state, setState] = useState();
|
|
730
|
-
const [view, setView] = useState();
|
|
731
|
-
useImperativeHandle(forwardedRef, () => ({
|
|
732
|
-
root,
|
|
733
|
-
state,
|
|
734
|
-
view
|
|
735
|
-
}), [
|
|
736
|
-
view,
|
|
737
|
-
state,
|
|
738
|
-
root
|
|
739
|
-
]);
|
|
740
|
-
useEffect(() => {
|
|
1743
|
+
useEffect2(() => {
|
|
741
1744
|
if (!root) {
|
|
742
1745
|
return;
|
|
743
1746
|
}
|
|
744
1747
|
const state2 = EditorState2.create({
|
|
745
1748
|
doc: model.text(),
|
|
746
1749
|
extensions: [
|
|
1750
|
+
readonly && EditorState2.readOnly.of(readonly),
|
|
747
1751
|
// TODO(burdon): Factor out VIM mode?
|
|
748
1752
|
editorMode === "vim" && vim(),
|
|
749
1753
|
// Theme.
|
|
750
|
-
|
|
751
|
-
|
|
1754
|
+
// TODO(burdon): Make optional.
|
|
1755
|
+
EditorView11.baseTheme(defaultTheme),
|
|
1756
|
+
EditorView11.theme(slots?.editor?.theme ?? {}),
|
|
752
1757
|
// TODO(burdon): themeMode doesn't change in storybooks.
|
|
753
|
-
|
|
1758
|
+
EditorView11.darkTheme.of(themeMode === "dark"),
|
|
754
1759
|
// Storage and replication.
|
|
755
1760
|
model.extension,
|
|
756
1761
|
// Custom.
|
|
@@ -758,7 +1763,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
758
1763
|
].filter(Boolean)
|
|
759
1764
|
});
|
|
760
1765
|
view?.destroy();
|
|
761
|
-
setView(new
|
|
1766
|
+
setView(new EditorView11({
|
|
762
1767
|
state: state2,
|
|
763
1768
|
parent: root
|
|
764
1769
|
}));
|
|
@@ -772,6 +1777,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
772
1777
|
root,
|
|
773
1778
|
model,
|
|
774
1779
|
themeMode,
|
|
1780
|
+
readonly,
|
|
775
1781
|
editorMode
|
|
776
1782
|
]);
|
|
777
1783
|
const handleKeyUp = useCallback((event) => {
|
|
@@ -799,13 +1805,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
799
1805
|
onKeyUp: handleKeyUp
|
|
800
1806
|
});
|
|
801
1807
|
});
|
|
802
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1808
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
803
1809
|
const { themeMode } = useThemeContext();
|
|
804
|
-
const slots =
|
|
1810
|
+
const slots = defaultsDeep2({}, _slots, defaultTextSlots);
|
|
805
1811
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
806
1812
|
ref: forwardedRef,
|
|
1813
|
+
readonly,
|
|
807
1814
|
extensions: [
|
|
808
1815
|
basicBundle({
|
|
1816
|
+
readonly,
|
|
809
1817
|
themeMode,
|
|
810
1818
|
placeholder: slots?.editor?.placeholder
|
|
811
1819
|
}),
|
|
@@ -815,13 +1823,15 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, .
|
|
|
815
1823
|
...props
|
|
816
1824
|
});
|
|
817
1825
|
});
|
|
818
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1826
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
819
1827
|
const { themeMode } = useThemeContext();
|
|
820
|
-
const slots =
|
|
1828
|
+
const slots = defaultsDeep2({}, _slots, defaultMarkdownSlots);
|
|
821
1829
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
822
1830
|
ref: forwardedRef,
|
|
1831
|
+
readonly,
|
|
823
1832
|
extensions: [
|
|
824
1833
|
markdownBundle({
|
|
1834
|
+
readonly,
|
|
825
1835
|
themeMode,
|
|
826
1836
|
placeholder: slots?.editor?.placeholder
|
|
827
1837
|
}),
|
|
@@ -833,7 +1843,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slot
|
|
|
833
1843
|
});
|
|
834
1844
|
var defaultSlots = {
|
|
835
1845
|
root: {
|
|
836
|
-
className:
|
|
1846
|
+
className: mx4("p-2", inputSurface)
|
|
837
1847
|
}
|
|
838
1848
|
};
|
|
839
1849
|
var defaultTextSlots = {
|
|
@@ -842,25 +1852,31 @@ var defaultTextSlots = {
|
|
|
842
1852
|
theme: textTheme
|
|
843
1853
|
}
|
|
844
1854
|
};
|
|
1855
|
+
var defaultMarkdownSlots = {
|
|
1856
|
+
...defaultSlots,
|
|
1857
|
+
editor: {
|
|
1858
|
+
theme: markdownTheme
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
845
1861
|
|
|
846
1862
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
847
|
-
import
|
|
848
|
-
import { useEffect as
|
|
1863
|
+
import get4 from "lodash.get";
|
|
1864
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
849
1865
|
import { yCollab } from "y-codemirror.next";
|
|
850
|
-
import { invariant } from "@dxos/invariant";
|
|
1866
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
851
1867
|
import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
|
|
852
1868
|
|
|
853
1869
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
854
|
-
import { Annotation, Facet, StateEffect, StateField as
|
|
855
|
-
import { ViewPlugin } from "@codemirror/view";
|
|
1870
|
+
import { Annotation, Facet, StateEffect as StateEffect2, StateField as StateField6 } from "@codemirror/state";
|
|
1871
|
+
import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
856
1872
|
import * as automerge2 from "@dxos/automerge/automerge";
|
|
857
1873
|
|
|
858
1874
|
// packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
|
|
859
1875
|
import { next as automerge } from "@dxos/automerge/automerge";
|
|
860
1876
|
|
|
861
|
-
// packages/ui/react-ui-editor/src/hooks/automerge/
|
|
1877
|
+
// packages/ui/react-ui-editor/src/hooks/automerge/translation/automerge-to-codemirror.ts
|
|
862
1878
|
import { ChangeSet } from "@codemirror/state";
|
|
863
|
-
var
|
|
1879
|
+
var automergeToCodemirror = (view, selection, target, patches) => {
|
|
864
1880
|
for (const patch of patches) {
|
|
865
1881
|
const changeSpec = handlePatch(patch, target, view.state);
|
|
866
1882
|
if (changeSpec != null) {
|
|
@@ -965,9 +1981,9 @@ var charPath = (textPath, candidatePath) => {
|
|
|
965
1981
|
return null;
|
|
966
1982
|
};
|
|
967
1983
|
|
|
968
|
-
// packages/ui/react-ui-editor/src/hooks/automerge/
|
|
1984
|
+
// packages/ui/react-ui-editor/src/hooks/automerge/translation/codemirror-to-automerge.ts
|
|
969
1985
|
import { next as am } from "@dxos/automerge/automerge";
|
|
970
|
-
var
|
|
1986
|
+
var codemirrorToAutomerge = (field, handle, transactions, state) => {
|
|
971
1987
|
const { lastHeads, path } = state.field(field);
|
|
972
1988
|
let hasChanges = false;
|
|
973
1989
|
for (const tr of transactions) {
|
|
@@ -1011,12 +2027,12 @@ var PatchSemaphore = class {
|
|
|
1011
2027
|
annotations: reconcileAnnotationType.of(true)
|
|
1012
2028
|
});
|
|
1013
2029
|
}
|
|
1014
|
-
let newHeads =
|
|
2030
|
+
let newHeads = codemirrorToAutomerge(this._field, handle, transactions, view.state);
|
|
1015
2031
|
if (newHeads === null || newHeads === void 0) {
|
|
1016
2032
|
newHeads = automerge.getHeads(handle.docSync());
|
|
1017
2033
|
}
|
|
1018
2034
|
const diff = automerge.equals(oldHeads, newHeads) ? [] : automerge.diff(handle.docSync(), oldHeads, newHeads);
|
|
1019
|
-
|
|
2035
|
+
automergeToCodemirror(view, selection, path, diff);
|
|
1020
2036
|
view.dispatch({
|
|
1021
2037
|
effects: updateHeads(newHeads),
|
|
1022
2038
|
annotations: reconcileAnnotationType.of({})
|
|
@@ -1030,7 +2046,7 @@ var PatchSemaphore = class {
|
|
|
1030
2046
|
};
|
|
1031
2047
|
|
|
1032
2048
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
1033
|
-
var effectType =
|
|
2049
|
+
var effectType = StateEffect2.define({});
|
|
1034
2050
|
var updateHeads = (newHeads) => effectType.of({
|
|
1035
2051
|
newHeads
|
|
1036
2052
|
});
|
|
@@ -1040,7 +2056,7 @@ var semaphoreFacet = Facet.define({
|
|
|
1040
2056
|
combine: (values) => values.at(-1)
|
|
1041
2057
|
});
|
|
1042
2058
|
var automergePlugin = (handle, path) => {
|
|
1043
|
-
const stateField =
|
|
2059
|
+
const stateField = StateField6.define({
|
|
1044
2060
|
create: () => ({
|
|
1045
2061
|
lastHeads: automerge2.getHeads(handle.docSync()),
|
|
1046
2062
|
unreconciledTransactions: [],
|
|
@@ -1070,7 +2086,7 @@ var automergePlugin = (handle, path) => {
|
|
|
1070
2086
|
}
|
|
1071
2087
|
});
|
|
1072
2088
|
const semaphore = new PatchSemaphore(stateField);
|
|
1073
|
-
const viewPlugin =
|
|
2089
|
+
const viewPlugin = ViewPlugin4.fromClass(class AutomergeCodemirrorViewPlugin {
|
|
1074
2090
|
constructor(view) {
|
|
1075
2091
|
this._handleChange = () => {
|
|
1076
2092
|
this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
|
|
@@ -1078,8 +2094,8 @@ var automergePlugin = (handle, path) => {
|
|
|
1078
2094
|
this._view = view;
|
|
1079
2095
|
handle.addListener("change", this._handleChange);
|
|
1080
2096
|
}
|
|
1081
|
-
update(
|
|
1082
|
-
if (
|
|
2097
|
+
update(update4) {
|
|
2098
|
+
if (update4.transactions.length > 0 && update4.transactions.some((t) => !isReconcileTx(t))) {
|
|
1083
2099
|
queueMicrotask(() => {
|
|
1084
2100
|
this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
|
|
1085
2101
|
});
|
|
@@ -1101,7 +2117,7 @@ var reconcileAnnotationType = Annotation.define();
|
|
|
1101
2117
|
var isReconcileTx = (tr) => !!tr.annotation(reconcileAnnotationType);
|
|
1102
2118
|
|
|
1103
2119
|
// packages/ui/react-ui-editor/src/hooks/yjs/cursors.ts
|
|
1104
|
-
import * as
|
|
2120
|
+
import * as random2 from "lib0/random";
|
|
1105
2121
|
var cursorColors = [
|
|
1106
2122
|
{
|
|
1107
2123
|
color: "#30bced",
|
|
@@ -1136,7 +2152,7 @@ var cursorColors = [
|
|
|
1136
2152
|
light: "#1be7ff33"
|
|
1137
2153
|
}
|
|
1138
2154
|
];
|
|
1139
|
-
var cursorColor = cursorColors[
|
|
2155
|
+
var cursorColor = cursorColors[random2.uint32() % cursorColors.length];
|
|
1140
2156
|
|
|
1141
2157
|
// packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts
|
|
1142
2158
|
import * as decoding from "lib0/decoding";
|
|
@@ -1144,7 +2160,7 @@ import * as encoding from "lib0/encoding";
|
|
|
1144
2160
|
import { Observable } from "lib0/observable";
|
|
1145
2161
|
import * as awarenessProtocol from "y-protocols/awareness";
|
|
1146
2162
|
import { log } from "@dxos/log";
|
|
1147
|
-
var
|
|
2163
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts";
|
|
1148
2164
|
var messageAwareness = 1;
|
|
1149
2165
|
var messageQueryAwareness = 3;
|
|
1150
2166
|
var SpaceAwarenessProvider = class extends Observable {
|
|
@@ -1181,7 +2197,7 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1181
2197
|
removed,
|
|
1182
2198
|
origin
|
|
1183
2199
|
}, {
|
|
1184
|
-
F:
|
|
2200
|
+
F: __dxlog_file3,
|
|
1185
2201
|
L: 67,
|
|
1186
2202
|
S: this,
|
|
1187
2203
|
C: (f, a) => f(...a)
|
|
@@ -1194,7 +2210,7 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1194
2210
|
}
|
|
1195
2211
|
_handleSpaceMessage({ payload }) {
|
|
1196
2212
|
log("space message", payload, {
|
|
1197
|
-
F:
|
|
2213
|
+
F: __dxlog_file3,
|
|
1198
2214
|
L: 79,
|
|
1199
2215
|
S: this,
|
|
1200
2216
|
C: (f, a) => f(...a)
|
|
@@ -1239,14 +2255,14 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1239
2255
|
};
|
|
1240
2256
|
|
|
1241
2257
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
1242
|
-
var
|
|
2258
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
1243
2259
|
var useTextModel = ({ identity, space, text }) => {
|
|
1244
2260
|
const [model, setModel] = useState2(() => createModel({
|
|
1245
2261
|
identity,
|
|
1246
2262
|
space,
|
|
1247
2263
|
text
|
|
1248
2264
|
}));
|
|
1249
|
-
|
|
2265
|
+
useEffect3(() => {
|
|
1250
2266
|
setModel(createModel({
|
|
1251
2267
|
identity,
|
|
1252
2268
|
space,
|
|
@@ -1260,44 +2276,45 @@ var useTextModel = ({ identity, space, text }) => {
|
|
|
1260
2276
|
return model;
|
|
1261
2277
|
};
|
|
1262
2278
|
var createModel = (options) => {
|
|
1263
|
-
const {
|
|
2279
|
+
const { text } = options;
|
|
1264
2280
|
if (isActualAutomergeObject(text)) {
|
|
1265
2281
|
return createAutomergeModel(options);
|
|
1266
2282
|
} else {
|
|
1267
|
-
if (!
|
|
2283
|
+
if (!text?.doc) {
|
|
1268
2284
|
return void 0;
|
|
1269
2285
|
}
|
|
1270
2286
|
return createYjsModel(options);
|
|
1271
2287
|
}
|
|
1272
2288
|
};
|
|
1273
2289
|
var createYjsModel = ({ identity, space, text }) => {
|
|
1274
|
-
|
|
1275
|
-
F:
|
|
1276
|
-
L:
|
|
2290
|
+
invariant3(text?.doc && text?.content, void 0, {
|
|
2291
|
+
F: __dxlog_file4,
|
|
2292
|
+
L: 81,
|
|
1277
2293
|
S: void 0,
|
|
1278
2294
|
A: [
|
|
1279
|
-
"
|
|
2295
|
+
"text?.doc && text?.content",
|
|
1280
2296
|
""
|
|
1281
2297
|
]
|
|
1282
2298
|
});
|
|
1283
|
-
const provider = new SpaceAwarenessProvider({
|
|
2299
|
+
const provider = space ? new SpaceAwarenessProvider({
|
|
1284
2300
|
space,
|
|
1285
2301
|
doc: text.doc,
|
|
1286
2302
|
channel: `yjs.awareness.${text.id}`
|
|
1287
|
-
});
|
|
2303
|
+
}) : void 0;
|
|
1288
2304
|
return {
|
|
1289
2305
|
id: text.doc.guid,
|
|
1290
2306
|
content: text.content,
|
|
1291
2307
|
text: () => text.content.toString(),
|
|
1292
|
-
|
|
1293
|
-
|
|
2308
|
+
ranges: [],
|
|
2309
|
+
extension: yCollab(text.content, provider?.awareness),
|
|
2310
|
+
awareness: provider?.awareness,
|
|
1294
2311
|
peer: identity ? {
|
|
1295
2312
|
id: identity.identityKey.toHex(),
|
|
1296
2313
|
name: identity.profile?.displayName
|
|
1297
2314
|
} : void 0
|
|
1298
2315
|
};
|
|
1299
2316
|
};
|
|
1300
|
-
var createAutomergeModel = ({ identity,
|
|
2317
|
+
var createAutomergeModel = ({ identity, text }) => {
|
|
1301
2318
|
const obj = text;
|
|
1302
2319
|
const doc = getRawDoc(obj, [
|
|
1303
2320
|
obj.field
|
|
@@ -1305,7 +2322,8 @@ var createAutomergeModel = ({ identity, space, text }) => {
|
|
|
1305
2322
|
return {
|
|
1306
2323
|
id: obj.id,
|
|
1307
2324
|
content: doc,
|
|
1308
|
-
text: () =>
|
|
2325
|
+
text: () => get4(doc.handle.docSync(), doc.path),
|
|
2326
|
+
ranges: [],
|
|
1309
2327
|
extension: automergePlugin(doc.handle, doc.path),
|
|
1310
2328
|
peer: identity ? {
|
|
1311
2329
|
id: identity.identityKey.toHex(),
|
|
@@ -1325,23 +2343,35 @@ export {
|
|
|
1325
2343
|
YXmlFragment,
|
|
1326
2344
|
autocomplete,
|
|
1327
2345
|
basicBundle,
|
|
2346
|
+
blast,
|
|
2347
|
+
code2 as code,
|
|
1328
2348
|
codeTheme,
|
|
2349
|
+
comments,
|
|
1329
2350
|
cursorColor,
|
|
2351
|
+
defaultMarkdownSlots,
|
|
2352
|
+
defaultOptions,
|
|
1330
2353
|
defaultSlots,
|
|
1331
2354
|
defaultTextSlots,
|
|
1332
2355
|
defaultTheme,
|
|
2356
|
+
demo,
|
|
2357
|
+
highlight,
|
|
2358
|
+
highlightDecorations,
|
|
2359
|
+
highlightStateField,
|
|
2360
|
+
image,
|
|
1333
2361
|
link,
|
|
1334
|
-
listener,
|
|
2362
|
+
listener2 as listener,
|
|
1335
2363
|
markdownBundle,
|
|
1336
2364
|
markdownHighlightStyle,
|
|
1337
2365
|
markdownTags,
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
2366
|
+
markdownTagsExtensions,
|
|
2367
|
+
markdownTheme,
|
|
2368
|
+
mention,
|
|
2369
|
+
table,
|
|
1341
2370
|
tags2 as tags,
|
|
1342
2371
|
tasklist,
|
|
1343
2372
|
textTheme,
|
|
1344
2373
|
tooltip,
|
|
2374
|
+
useHighlights,
|
|
1345
2375
|
useTextModel
|
|
1346
2376
|
};
|
|
1347
2377
|
//# sourceMappingURL=index.mjs.map
|