@dxos/react-ui-editor 0.3.10-main.3cfd481 → 0.3.10-main.4001251
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 +1419 -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 +46 -43
- 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 +113 -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, highlightActiveLine, 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,202 @@ 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
|
-
|
|
1158
|
+
drawSelection2(),
|
|
365
1159
|
highlightActiveLine(),
|
|
366
|
-
highlightActiveLineGutter(),
|
|
367
|
-
highlightSelectionMatches(),
|
|
368
|
-
highlightSpecialChars(),
|
|
369
1160
|
history(),
|
|
370
1161
|
indentOnInput(),
|
|
371
|
-
|
|
372
|
-
keymap2.of([
|
|
373
|
-
...closeBracketsKeymap,
|
|
374
|
-
// ...completionKeymap,
|
|
375
|
-
...defaultKeymap,
|
|
376
|
-
...foldKeymap,
|
|
377
|
-
...historyKeymap,
|
|
378
|
-
...lintKeymap,
|
|
379
|
-
...searchKeymap,
|
|
380
|
-
indentWithTab
|
|
381
|
-
]),
|
|
1162
|
+
_placeholder && placeholder2(_placeholder),
|
|
382
1163
|
// Main extension.
|
|
383
1164
|
// https://github.com/codemirror/lang-markdown
|
|
384
1165
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -393,102 +1174,231 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
393
1174
|
codeLanguages: languages,
|
|
394
1175
|
// Parser extensions.
|
|
395
1176
|
extensions: [
|
|
396
|
-
// GFM
|
|
397
|
-
|
|
1177
|
+
// GFM provided by default.
|
|
1178
|
+
markdownTagsExtensions
|
|
398
1179
|
]
|
|
399
1180
|
}),
|
|
1181
|
+
// https://github.com/codemirror/theme-one-dark
|
|
1182
|
+
themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2),
|
|
400
1183
|
// 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)
|
|
1184
|
+
syntaxHighlighting2(markdownHighlightStyle(readonly))
|
|
404
1185
|
].filter(Boolean);
|
|
405
1186
|
};
|
|
1187
|
+
var customKeymap = () => keymap5.of([
|
|
1188
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1189
|
+
indentWithTab,
|
|
1190
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1191
|
+
...standardKeymap,
|
|
1192
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
1193
|
+
...historyKeymap,
|
|
1194
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
1195
|
+
...closeBracketsKeymap,
|
|
1196
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
1197
|
+
...searchKeymap
|
|
1198
|
+
]);
|
|
1199
|
+
|
|
1200
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/mention.ts
|
|
1201
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
1202
|
+
var mention = ({ onSearch }) => {
|
|
1203
|
+
return autocompletion2({
|
|
1204
|
+
closeOnBlur: false,
|
|
1205
|
+
override: [
|
|
1206
|
+
(context) => {
|
|
1207
|
+
const match = context.matchBefore(/@(\w+)?/);
|
|
1208
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
console.log(match);
|
|
1212
|
+
return {
|
|
1213
|
+
from: match.from,
|
|
1214
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
|
1215
|
+
label: `@${value}`
|
|
1216
|
+
}))
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
]
|
|
1220
|
+
});
|
|
1221
|
+
};
|
|
1222
|
+
|
|
1223
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/table.ts
|
|
1224
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1225
|
+
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
|
|
1226
|
+
import { Decoration as Decoration6, EditorView as EditorView9, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1227
|
+
var table = (options = {}) => {
|
|
1228
|
+
return StateField5.define({
|
|
1229
|
+
create: (state) => update3(state, options),
|
|
1230
|
+
update: (_, tr) => update3(tr.state, options),
|
|
1231
|
+
provide: (field) => EditorView9.decorations.from(field)
|
|
1232
|
+
});
|
|
1233
|
+
};
|
|
1234
|
+
var update3 = (state, options) => {
|
|
1235
|
+
const builder = new RangeSetBuilder3();
|
|
1236
|
+
const cursor = state.selection.main.head;
|
|
1237
|
+
const tables = [];
|
|
1238
|
+
const getTable = () => tables[tables.length - 1];
|
|
1239
|
+
const getRow = () => {
|
|
1240
|
+
const table2 = getTable();
|
|
1241
|
+
return table2.rows?.[table2.rows.length - 1];
|
|
1242
|
+
};
|
|
1243
|
+
syntaxTree3(state).iterate({
|
|
1244
|
+
enter: (node) => {
|
|
1245
|
+
switch (node.name) {
|
|
1246
|
+
case "Table": {
|
|
1247
|
+
tables.push({
|
|
1248
|
+
from: node.from,
|
|
1249
|
+
to: node.to
|
|
1250
|
+
});
|
|
1251
|
+
break;
|
|
1252
|
+
}
|
|
1253
|
+
case "TableHeader": {
|
|
1254
|
+
getTable().header = [];
|
|
1255
|
+
break;
|
|
1256
|
+
}
|
|
1257
|
+
case "TableRow": {
|
|
1258
|
+
(getTable().rows ??= []).push([]);
|
|
1259
|
+
break;
|
|
1260
|
+
}
|
|
1261
|
+
case "TableCell": {
|
|
1262
|
+
const row = getRow();
|
|
1263
|
+
if (row) {
|
|
1264
|
+
row.push(state.sliceDoc(node.from, node.to));
|
|
1265
|
+
} else {
|
|
1266
|
+
getTable().header?.push(state.sliceDoc(node.from, node.to));
|
|
1267
|
+
}
|
|
1268
|
+
break;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1273
|
+
tables.forEach((table2) => {
|
|
1274
|
+
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
1275
|
+
hide && builder.add(table2.from, table2.to, Decoration6.replace({
|
|
1276
|
+
widget: new TableWidget(table2)
|
|
1277
|
+
}));
|
|
1278
|
+
builder.add(table2.from, table2.to, Decoration6.mark({
|
|
1279
|
+
class: "cm-table"
|
|
1280
|
+
}));
|
|
1281
|
+
});
|
|
1282
|
+
return builder.finish();
|
|
1283
|
+
};
|
|
1284
|
+
var TableWidget = class extends WidgetType4 {
|
|
1285
|
+
constructor(_table) {
|
|
1286
|
+
super();
|
|
1287
|
+
this._table = _table;
|
|
1288
|
+
}
|
|
1289
|
+
eq(other) {
|
|
1290
|
+
return this._table.from === other?._table?.from;
|
|
1291
|
+
}
|
|
1292
|
+
toDOM(view) {
|
|
1293
|
+
const table2 = document.createElement("table");
|
|
1294
|
+
{
|
|
1295
|
+
const header = table2.appendChild(document.createElement("thead"));
|
|
1296
|
+
const tr = header.appendChild(document.createElement("tr"));
|
|
1297
|
+
this._table.header?.forEach((cell) => {
|
|
1298
|
+
const th = document.createElement("th");
|
|
1299
|
+
th.setAttribute("class", "cm-table-head");
|
|
1300
|
+
tr.appendChild(th).textContent = cell;
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
{
|
|
1304
|
+
const body = table2.appendChild(document.createElement("tbody"));
|
|
1305
|
+
this._table.rows?.forEach((row) => {
|
|
1306
|
+
const tr = body.appendChild(document.createElement("tr"));
|
|
1307
|
+
row.forEach((cell) => {
|
|
1308
|
+
const td = document.createElement("td");
|
|
1309
|
+
td.setAttribute("class", "cm-table-cell");
|
|
1310
|
+
tr.appendChild(td).textContent = cell;
|
|
1311
|
+
});
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
return table2;
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
406
1317
|
|
|
407
1318
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/tasklist.ts
|
|
408
|
-
import {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
1319
|
+
import { EditorView as EditorView10, Decoration as Decoration7, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
|
|
1320
|
+
var styles4 = EditorView10.baseTheme({
|
|
1321
|
+
"& .cm-task-item": {
|
|
1322
|
+
paddingLeft: "4px",
|
|
1323
|
+
paddingRight: "8px"
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1326
|
+
var CheckboxWidget = class extends WidgetType5 {
|
|
1327
|
+
constructor(_pos, _checked, _indent, _onCheck) {
|
|
413
1328
|
super();
|
|
414
1329
|
this._pos = _pos;
|
|
415
|
-
this._getCursor = _getCursor;
|
|
416
1330
|
this._checked = _checked;
|
|
1331
|
+
this._indent = _indent;
|
|
1332
|
+
this._onCheck = _onCheck;
|
|
417
1333
|
}
|
|
418
1334
|
eq(other) {
|
|
419
|
-
return this._pos === other._pos && this._checked === other._checked;
|
|
1335
|
+
return this._pos === other._pos && this._checked === other._checked && this._indent === other._indent;
|
|
420
1336
|
}
|
|
421
1337
|
toDOM(view) {
|
|
422
1338
|
const wrap = document.createElement("span");
|
|
423
|
-
wrap.setAttribute("aria-hidden", "true");
|
|
424
1339
|
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
|
-
};
|
|
1340
|
+
wrap.setAttribute("aria-hidden", "true");
|
|
1341
|
+
wrap.style.setProperty("margin-left", this._indent * 24 + "px");
|
|
1342
|
+
const input = wrap.appendChild(document.createElement("input"));
|
|
1343
|
+
input.type = "checkbox";
|
|
1344
|
+
input.checked = this._checked;
|
|
1345
|
+
if (!this._onCheck) {
|
|
1346
|
+
input.setAttribute("disabled", "true");
|
|
1347
|
+
}
|
|
1348
|
+
if (this._onCheck) {
|
|
1349
|
+
input.onchange = (event) => {
|
|
1350
|
+
this._onCheck?.(event.target.checked);
|
|
1351
|
+
return true;
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
443
1354
|
return wrap;
|
|
444
1355
|
}
|
|
445
|
-
// TODO(burdon): Remove listener?
|
|
446
|
-
// override destroy() {
|
|
447
|
-
// console.log('destroy', this._pos);
|
|
448
|
-
// }
|
|
449
1356
|
ignoreEvent() {
|
|
450
1357
|
return false;
|
|
451
1358
|
}
|
|
452
1359
|
};
|
|
453
|
-
var
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
1360
|
+
var tasklist = (options = {}) => {
|
|
1361
|
+
const taskMatcher = new MatchDecorator2({
|
|
1362
|
+
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
1363
|
+
decoration: (match, view, pos) => {
|
|
1364
|
+
const indent = Math.floor(match[1].length / 2);
|
|
1365
|
+
const checked = match[2] === "x" || match[2] === "X";
|
|
1366
|
+
return Decoration7.replace({
|
|
1367
|
+
widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
|
|
1368
|
+
const idx = pos + match[0].indexOf("[") + 1;
|
|
1369
|
+
view.dispatch({
|
|
1370
|
+
changes: {
|
|
1371
|
+
from: idx,
|
|
1372
|
+
to: idx + 1,
|
|
1373
|
+
insert: checked2 ? "x" : " "
|
|
1374
|
+
},
|
|
1375
|
+
// TODO(burdon): Restore cursor position? More useful to move to end of line (can indent).
|
|
1376
|
+
selection: {
|
|
1377
|
+
anchor: idx + 3
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
})
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
460
1383
|
});
|
|
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)
|
|
1384
|
+
const tasks = ViewPlugin3.fromClass(class {
|
|
1385
|
+
constructor(view) {
|
|
1386
|
+
this.tasks = taskMatcher.createDeco(view);
|
|
1387
|
+
}
|
|
1388
|
+
update(update4) {
|
|
1389
|
+
this.tasks = taskMatcher.updateDeco(update4, this.tasks);
|
|
1390
|
+
}
|
|
1391
|
+
}, {
|
|
1392
|
+
decorations: (value) => value.tasks,
|
|
1393
|
+
provide: (plugin) => EditorView10.atomicRanges.of((view) => {
|
|
1394
|
+
return view.plugin(plugin)?.tasks || Decoration7.none;
|
|
480
1395
|
})
|
|
1396
|
+
});
|
|
1397
|
+
return [
|
|
1398
|
+
tasks,
|
|
1399
|
+
styles4
|
|
481
1400
|
];
|
|
482
1401
|
};
|
|
483
|
-
var styles = EditorView4.baseTheme({
|
|
484
|
-
"& .cm-task-item": {
|
|
485
|
-
padding: "0 4px"
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
var tasklist = () => [
|
|
489
|
-
statefield(),
|
|
490
|
-
styles
|
|
491
|
-
];
|
|
492
1402
|
|
|
493
1403
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/tooltip.tsx
|
|
494
1404
|
import { hoverTooltip } from "@codemirror/view";
|
|
@@ -535,7 +1445,7 @@ var tooltip = ({ onHover, regexp = markdownLinkRegexp }) => hoverTooltip((view,
|
|
|
535
1445
|
});
|
|
536
1446
|
|
|
537
1447
|
// packages/ui/react-ui-editor/src/components/TextEditor/themes/default.ts
|
|
538
|
-
import
|
|
1448
|
+
import get3 from "lodash.get";
|
|
539
1449
|
var defaultTheme = {
|
|
540
1450
|
//
|
|
541
1451
|
// Main layout:
|
|
@@ -552,7 +1462,8 @@ var defaultTheme = {
|
|
|
552
1462
|
outline: "none"
|
|
553
1463
|
},
|
|
554
1464
|
"& .cm-scroller": {
|
|
555
|
-
overflow: "visible"
|
|
1465
|
+
overflow: "visible",
|
|
1466
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
556
1467
|
},
|
|
557
1468
|
"& .cm-content": {
|
|
558
1469
|
padding: 0,
|
|
@@ -560,20 +1471,20 @@ var defaultTheme = {
|
|
|
560
1471
|
fontSize: "16px"
|
|
561
1472
|
},
|
|
562
1473
|
"&light .cm-content": {
|
|
563
|
-
color:
|
|
1474
|
+
color: get3(tokens, "extend.colors.neutral.900", "black"),
|
|
564
1475
|
caretColor: "black"
|
|
565
1476
|
},
|
|
566
1477
|
"&dark .cm-content": {
|
|
567
|
-
color:
|
|
1478
|
+
color: get3(tokens, "extend.colors.neutral.100", "white"),
|
|
568
1479
|
caretColor: "white"
|
|
569
1480
|
},
|
|
570
1481
|
//
|
|
571
1482
|
// Cursor
|
|
572
1483
|
//
|
|
573
|
-
"&light .cm-cursor": {
|
|
1484
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
574
1485
|
borderLeft: "2px solid black"
|
|
575
1486
|
},
|
|
576
|
-
"&dark .cm-cursor": {
|
|
1487
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
577
1488
|
borderLeft: "2px solid white"
|
|
578
1489
|
},
|
|
579
1490
|
"& .cm-placeholder": {
|
|
@@ -593,16 +1504,16 @@ var defaultTheme = {
|
|
|
593
1504
|
// selection
|
|
594
1505
|
//
|
|
595
1506
|
"&light .cm-selectionBackground, &light.cm-focused .cm-selectionBackground": {
|
|
596
|
-
background:
|
|
1507
|
+
background: get3(tokens, "extend.colors.primary.150", "#00ffff")
|
|
597
1508
|
},
|
|
598
1509
|
"&dark .cm-selectionBackground, &dark.cm-focused .cm-selectionBackground": {
|
|
599
|
-
background:
|
|
1510
|
+
background: get3(tokens, "extend.colors.primary.850", "#00ffff")
|
|
600
1511
|
},
|
|
601
1512
|
"&light .cm-selectionMatch": {
|
|
602
|
-
background:
|
|
1513
|
+
background: get3(tokens, "extend.colors.primary.250", "#00ffff") + "44"
|
|
603
1514
|
},
|
|
604
1515
|
"&dark .cm-selectionMatch": {
|
|
605
|
-
background:
|
|
1516
|
+
background: get3(tokens, "extend.colors.primary.600", "#00ffff") + "44"
|
|
606
1517
|
},
|
|
607
1518
|
//
|
|
608
1519
|
// collaboration
|
|
@@ -635,12 +1546,12 @@ var defaultTheme = {
|
|
|
635
1546
|
// link
|
|
636
1547
|
//
|
|
637
1548
|
"& .cm-link": {
|
|
638
|
-
color:
|
|
1549
|
+
color: get3(tokens, "extend.colors.primary.500"),
|
|
639
1550
|
textDecorationLine: "underline",
|
|
640
1551
|
textDecorationThickness: "1px",
|
|
641
1552
|
textUnderlineOffset: "2px",
|
|
642
1553
|
borderRadius: ".125rem",
|
|
643
|
-
fontFamily:
|
|
1554
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
644
1555
|
},
|
|
645
1556
|
//
|
|
646
1557
|
// tooltip
|
|
@@ -648,14 +1559,61 @@ var defaultTheme = {
|
|
|
648
1559
|
"& .cm-tooltip": {
|
|
649
1560
|
border: "none"
|
|
650
1561
|
},
|
|
651
|
-
|
|
652
|
-
//
|
|
1562
|
+
"& .cm-tooltip-below": {},
|
|
1563
|
+
//
|
|
1564
|
+
// autocomplete
|
|
1565
|
+
//
|
|
1566
|
+
"& .cm-tooltip-autocomplete": {
|
|
1567
|
+
marginTop: "4px",
|
|
1568
|
+
marginLeft: "-3px"
|
|
1569
|
+
},
|
|
1570
|
+
"& .cm-tooltip-autocomplete ul li": {},
|
|
1571
|
+
"& .cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
1572
|
+
"& .cm-completionIcon": {
|
|
1573
|
+
display: "none"
|
|
1574
|
+
},
|
|
1575
|
+
"& .cm-completionLabel": {
|
|
1576
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1577
|
+
},
|
|
1578
|
+
"& .cm-completionMatchedText": {
|
|
1579
|
+
textDecoration: "none"
|
|
1580
|
+
},
|
|
1581
|
+
//
|
|
1582
|
+
// widgets
|
|
1583
|
+
//
|
|
1584
|
+
"& .cm-widgetBuffer": {
|
|
1585
|
+
display: "none",
|
|
1586
|
+
height: 0
|
|
1587
|
+
},
|
|
1588
|
+
//
|
|
1589
|
+
// table
|
|
1590
|
+
//
|
|
1591
|
+
"& .cm-table *": {
|
|
1592
|
+
fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
1593
|
+
textDecoration: "none !important"
|
|
1594
|
+
},
|
|
1595
|
+
"& .cm-table-head": {
|
|
1596
|
+
padding: "2px 16px 2px 0px",
|
|
1597
|
+
borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
|
|
1598
|
+
fontWeight: 100,
|
|
1599
|
+
textAlign: "left",
|
|
1600
|
+
color: get3(tokens, "extend.colors.neutral.500")
|
|
1601
|
+
},
|
|
1602
|
+
"& .cm-table-cell": {
|
|
1603
|
+
padding: "2px 16px 2px 0px"
|
|
1604
|
+
},
|
|
1605
|
+
//
|
|
1606
|
+
// image
|
|
1607
|
+
//
|
|
1608
|
+
"& .cm-image": {
|
|
1609
|
+
margin: "0.5rem 0"
|
|
1610
|
+
},
|
|
653
1611
|
//
|
|
654
1612
|
// font size
|
|
655
1613
|
// 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
1614
|
//
|
|
657
|
-
...Object.keys(
|
|
658
|
-
const height =
|
|
1615
|
+
...Object.keys(get3(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
|
|
1616
|
+
const height = get3(tokens, [
|
|
659
1617
|
"extend",
|
|
660
1618
|
"fontSize",
|
|
661
1619
|
fontSize,
|
|
@@ -672,40 +1630,99 @@ var defaultTheme = {
|
|
|
672
1630
|
height
|
|
673
1631
|
};
|
|
674
1632
|
return acc;
|
|
675
|
-
}, {})
|
|
1633
|
+
}, {}),
|
|
1634
|
+
/**
|
|
1635
|
+
* Panels
|
|
1636
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
1637
|
+
*
|
|
1638
|
+
* Find/replace panel.
|
|
1639
|
+
* <div class="cm-announced">...</div>
|
|
1640
|
+
* <div class="cm-scroller">...</div>
|
|
1641
|
+
* <div class="cm-panels cm-panels-bottom">
|
|
1642
|
+
* <div class="cm-search cm-panel">
|
|
1643
|
+
* <input class="cm-textfield" />
|
|
1644
|
+
* <button class="cm-button">...</button>
|
|
1645
|
+
* <label><input type="checkbox" />...</label>
|
|
1646
|
+
* </div>
|
|
1647
|
+
* </div
|
|
1648
|
+
*/
|
|
1649
|
+
"& .cm-panels": {
|
|
1650
|
+
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`,
|
|
1651
|
+
borderBottom: "none"
|
|
1652
|
+
},
|
|
1653
|
+
"& .cm-panel": {
|
|
1654
|
+
background: get3(tokens, "extend.colors.neutral.50"),
|
|
1655
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1656
|
+
},
|
|
1657
|
+
"& .cm-button": {
|
|
1658
|
+
margin: "4px",
|
|
1659
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
1660
|
+
background: get3(tokens, "extend.colors.neutral.100"),
|
|
1661
|
+
border: "none"
|
|
1662
|
+
},
|
|
1663
|
+
"& .cm-searchMatch": {
|
|
1664
|
+
backgroundColor: get3(tokens, "extend.colors.yellow.100")
|
|
1665
|
+
},
|
|
1666
|
+
"& .cm-searchMatch.cm-searchMatch-selected": {
|
|
1667
|
+
backgroundColor: get3(tokens, "extend.colors.primary.100")
|
|
1668
|
+
}
|
|
676
1669
|
};
|
|
677
1670
|
var textTheme = {
|
|
678
1671
|
"& .cm-scroller": {
|
|
679
|
-
fontFamily:
|
|
1672
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1673
|
+
},
|
|
1674
|
+
"& .cm-placeholder": {
|
|
1675
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
var markdownTheme = {
|
|
1679
|
+
// NOTE: Must leave base font family as is (i.e., monospace) due to fenced code blocks.
|
|
1680
|
+
"& .cm-placeholder": {
|
|
1681
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
680
1682
|
}
|
|
681
1683
|
};
|
|
682
1684
|
var codeTheme = {
|
|
683
1685
|
"& .cm-scroller": {
|
|
684
|
-
fontFamily:
|
|
1686
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
1687
|
+
},
|
|
1688
|
+
"& .cm-placeholder": {
|
|
1689
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
685
1690
|
}
|
|
686
1691
|
};
|
|
687
1692
|
|
|
688
1693
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
689
1694
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
690
|
-
import { EditorView as
|
|
1695
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
691
1696
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
692
1697
|
import { vim } from "@replit/codemirror-vim";
|
|
693
|
-
import
|
|
694
|
-
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
|
|
1698
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
1699
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useState } from "react";
|
|
695
1700
|
import { generateName } from "@dxos/display-name";
|
|
696
1701
|
import { useThemeContext } from "@dxos/react-ui";
|
|
697
|
-
import { getColorForValue, inputSurface, mx as
|
|
1702
|
+
import { getColorForValue, inputSurface, mx as mx4 } from "@dxos/react-ui-theme";
|
|
698
1703
|
var EditorModes = [
|
|
699
1704
|
"default",
|
|
700
1705
|
"vim"
|
|
701
1706
|
];
|
|
702
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots = defaultSlots
|
|
1707
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode, extensions = [], slots = defaultSlots }, forwardedRef) => {
|
|
703
1708
|
const { themeMode } = useThemeContext();
|
|
704
1709
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
705
1710
|
tabBehavior: "limited"
|
|
706
1711
|
});
|
|
1712
|
+
const [root, setRoot] = useState(null);
|
|
1713
|
+
const [state, setState] = useState();
|
|
1714
|
+
const [view, setView] = useState();
|
|
1715
|
+
useImperativeHandle(forwardedRef, () => ({
|
|
1716
|
+
root,
|
|
1717
|
+
state,
|
|
1718
|
+
view
|
|
1719
|
+
}), [
|
|
1720
|
+
view,
|
|
1721
|
+
state,
|
|
1722
|
+
root
|
|
1723
|
+
]);
|
|
707
1724
|
const { awareness, peer } = model;
|
|
708
|
-
|
|
1725
|
+
useEffect2(() => {
|
|
709
1726
|
if (awareness && peer) {
|
|
710
1727
|
awareness.setLocalStateField("user", {
|
|
711
1728
|
name: peer.name ?? generateName(peer.id),
|
|
@@ -725,32 +1742,22 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
725
1742
|
peer,
|
|
726
1743
|
themeMode
|
|
727
1744
|
]);
|
|
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(() => {
|
|
1745
|
+
useEffect2(() => {
|
|
741
1746
|
if (!root) {
|
|
742
1747
|
return;
|
|
743
1748
|
}
|
|
744
1749
|
const state2 = EditorState2.create({
|
|
745
1750
|
doc: model.text(),
|
|
746
1751
|
extensions: [
|
|
1752
|
+
readonly && EditorState2.readOnly.of(readonly),
|
|
747
1753
|
// TODO(burdon): Factor out VIM mode?
|
|
748
1754
|
editorMode === "vim" && vim(),
|
|
749
1755
|
// Theme.
|
|
750
|
-
|
|
751
|
-
|
|
1756
|
+
// TODO(burdon): Make optional.
|
|
1757
|
+
EditorView11.baseTheme(defaultTheme),
|
|
1758
|
+
EditorView11.theme(slots?.editor?.theme ?? {}),
|
|
752
1759
|
// TODO(burdon): themeMode doesn't change in storybooks.
|
|
753
|
-
|
|
1760
|
+
EditorView11.darkTheme.of(themeMode === "dark"),
|
|
754
1761
|
// Storage and replication.
|
|
755
1762
|
model.extension,
|
|
756
1763
|
// Custom.
|
|
@@ -758,7 +1765,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
758
1765
|
].filter(Boolean)
|
|
759
1766
|
});
|
|
760
1767
|
view?.destroy();
|
|
761
|
-
setView(new
|
|
1768
|
+
setView(new EditorView11({
|
|
762
1769
|
state: state2,
|
|
763
1770
|
parent: root
|
|
764
1771
|
}));
|
|
@@ -772,6 +1779,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
772
1779
|
root,
|
|
773
1780
|
model,
|
|
774
1781
|
themeMode,
|
|
1782
|
+
readonly,
|
|
775
1783
|
editorMode
|
|
776
1784
|
]);
|
|
777
1785
|
const handleKeyUp = useCallback((event) => {
|
|
@@ -799,13 +1807,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
799
1807
|
onKeyUp: handleKeyUp
|
|
800
1808
|
});
|
|
801
1809
|
});
|
|
802
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1810
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
803
1811
|
const { themeMode } = useThemeContext();
|
|
804
|
-
const slots =
|
|
1812
|
+
const slots = defaultsDeep2({}, _slots, defaultTextSlots);
|
|
805
1813
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
806
1814
|
ref: forwardedRef,
|
|
1815
|
+
readonly,
|
|
807
1816
|
extensions: [
|
|
808
1817
|
basicBundle({
|
|
1818
|
+
readonly,
|
|
809
1819
|
themeMode,
|
|
810
1820
|
placeholder: slots?.editor?.placeholder
|
|
811
1821
|
}),
|
|
@@ -815,13 +1825,15 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, .
|
|
|
815
1825
|
...props
|
|
816
1826
|
});
|
|
817
1827
|
});
|
|
818
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1828
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
819
1829
|
const { themeMode } = useThemeContext();
|
|
820
|
-
const slots =
|
|
1830
|
+
const slots = defaultsDeep2({}, _slots, defaultMarkdownSlots);
|
|
821
1831
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
822
1832
|
ref: forwardedRef,
|
|
1833
|
+
readonly,
|
|
823
1834
|
extensions: [
|
|
824
1835
|
markdownBundle({
|
|
1836
|
+
readonly,
|
|
825
1837
|
themeMode,
|
|
826
1838
|
placeholder: slots?.editor?.placeholder
|
|
827
1839
|
}),
|
|
@@ -833,7 +1845,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slot
|
|
|
833
1845
|
});
|
|
834
1846
|
var defaultSlots = {
|
|
835
1847
|
root: {
|
|
836
|
-
className:
|
|
1848
|
+
className: mx4("p-2", inputSurface)
|
|
837
1849
|
}
|
|
838
1850
|
};
|
|
839
1851
|
var defaultTextSlots = {
|
|
@@ -842,25 +1854,31 @@ var defaultTextSlots = {
|
|
|
842
1854
|
theme: textTheme
|
|
843
1855
|
}
|
|
844
1856
|
};
|
|
1857
|
+
var defaultMarkdownSlots = {
|
|
1858
|
+
...defaultSlots,
|
|
1859
|
+
editor: {
|
|
1860
|
+
theme: markdownTheme
|
|
1861
|
+
}
|
|
1862
|
+
};
|
|
845
1863
|
|
|
846
1864
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
847
|
-
import
|
|
848
|
-
import { useEffect as
|
|
1865
|
+
import get4 from "lodash.get";
|
|
1866
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
849
1867
|
import { yCollab } from "y-codemirror.next";
|
|
850
|
-
import { invariant } from "@dxos/invariant";
|
|
1868
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
851
1869
|
import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
|
|
852
1870
|
|
|
853
1871
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
854
|
-
import { Annotation, Facet, StateEffect, StateField as
|
|
855
|
-
import { ViewPlugin } from "@codemirror/view";
|
|
1872
|
+
import { Annotation, Facet, StateEffect as StateEffect2, StateField as StateField6 } from "@codemirror/state";
|
|
1873
|
+
import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
856
1874
|
import * as automerge2 from "@dxos/automerge/automerge";
|
|
857
1875
|
|
|
858
1876
|
// packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
|
|
859
1877
|
import { next as automerge } from "@dxos/automerge/automerge";
|
|
860
1878
|
|
|
861
|
-
// packages/ui/react-ui-editor/src/hooks/automerge/
|
|
1879
|
+
// packages/ui/react-ui-editor/src/hooks/automerge/translation/automerge-to-codemirror.ts
|
|
862
1880
|
import { ChangeSet } from "@codemirror/state";
|
|
863
|
-
var
|
|
1881
|
+
var automergeToCodemirror = (view, selection, target, patches) => {
|
|
864
1882
|
for (const patch of patches) {
|
|
865
1883
|
const changeSpec = handlePatch(patch, target, view.state);
|
|
866
1884
|
if (changeSpec != null) {
|
|
@@ -965,9 +1983,9 @@ var charPath = (textPath, candidatePath) => {
|
|
|
965
1983
|
return null;
|
|
966
1984
|
};
|
|
967
1985
|
|
|
968
|
-
// packages/ui/react-ui-editor/src/hooks/automerge/
|
|
1986
|
+
// packages/ui/react-ui-editor/src/hooks/automerge/translation/codemirror-to-automerge.ts
|
|
969
1987
|
import { next as am } from "@dxos/automerge/automerge";
|
|
970
|
-
var
|
|
1988
|
+
var codemirrorToAutomerge = (field, handle, transactions, state) => {
|
|
971
1989
|
const { lastHeads, path } = state.field(field);
|
|
972
1990
|
let hasChanges = false;
|
|
973
1991
|
for (const tr of transactions) {
|
|
@@ -1011,12 +2029,12 @@ var PatchSemaphore = class {
|
|
|
1011
2029
|
annotations: reconcileAnnotationType.of(true)
|
|
1012
2030
|
});
|
|
1013
2031
|
}
|
|
1014
|
-
let newHeads =
|
|
2032
|
+
let newHeads = codemirrorToAutomerge(this._field, handle, transactions, view.state);
|
|
1015
2033
|
if (newHeads === null || newHeads === void 0) {
|
|
1016
2034
|
newHeads = automerge.getHeads(handle.docSync());
|
|
1017
2035
|
}
|
|
1018
2036
|
const diff = automerge.equals(oldHeads, newHeads) ? [] : automerge.diff(handle.docSync(), oldHeads, newHeads);
|
|
1019
|
-
|
|
2037
|
+
automergeToCodemirror(view, selection, path, diff);
|
|
1020
2038
|
view.dispatch({
|
|
1021
2039
|
effects: updateHeads(newHeads),
|
|
1022
2040
|
annotations: reconcileAnnotationType.of({})
|
|
@@ -1030,7 +2048,7 @@ var PatchSemaphore = class {
|
|
|
1030
2048
|
};
|
|
1031
2049
|
|
|
1032
2050
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
1033
|
-
var effectType =
|
|
2051
|
+
var effectType = StateEffect2.define({});
|
|
1034
2052
|
var updateHeads = (newHeads) => effectType.of({
|
|
1035
2053
|
newHeads
|
|
1036
2054
|
});
|
|
@@ -1040,7 +2058,7 @@ var semaphoreFacet = Facet.define({
|
|
|
1040
2058
|
combine: (values) => values.at(-1)
|
|
1041
2059
|
});
|
|
1042
2060
|
var automergePlugin = (handle, path) => {
|
|
1043
|
-
const stateField =
|
|
2061
|
+
const stateField = StateField6.define({
|
|
1044
2062
|
create: () => ({
|
|
1045
2063
|
lastHeads: automerge2.getHeads(handle.docSync()),
|
|
1046
2064
|
unreconciledTransactions: [],
|
|
@@ -1070,7 +2088,7 @@ var automergePlugin = (handle, path) => {
|
|
|
1070
2088
|
}
|
|
1071
2089
|
});
|
|
1072
2090
|
const semaphore = new PatchSemaphore(stateField);
|
|
1073
|
-
const viewPlugin =
|
|
2091
|
+
const viewPlugin = ViewPlugin4.fromClass(class AutomergeCodemirrorViewPlugin {
|
|
1074
2092
|
constructor(view) {
|
|
1075
2093
|
this._handleChange = () => {
|
|
1076
2094
|
this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
|
|
@@ -1078,8 +2096,8 @@ var automergePlugin = (handle, path) => {
|
|
|
1078
2096
|
this._view = view;
|
|
1079
2097
|
handle.addListener("change", this._handleChange);
|
|
1080
2098
|
}
|
|
1081
|
-
update(
|
|
1082
|
-
if (
|
|
2099
|
+
update(update4) {
|
|
2100
|
+
if (update4.transactions.length > 0 && update4.transactions.some((t) => !isReconcileTx(t))) {
|
|
1083
2101
|
queueMicrotask(() => {
|
|
1084
2102
|
this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
|
|
1085
2103
|
});
|
|
@@ -1101,7 +2119,7 @@ var reconcileAnnotationType = Annotation.define();
|
|
|
1101
2119
|
var isReconcileTx = (tr) => !!tr.annotation(reconcileAnnotationType);
|
|
1102
2120
|
|
|
1103
2121
|
// packages/ui/react-ui-editor/src/hooks/yjs/cursors.ts
|
|
1104
|
-
import * as
|
|
2122
|
+
import * as random2 from "lib0/random";
|
|
1105
2123
|
var cursorColors = [
|
|
1106
2124
|
{
|
|
1107
2125
|
color: "#30bced",
|
|
@@ -1136,7 +2154,7 @@ var cursorColors = [
|
|
|
1136
2154
|
light: "#1be7ff33"
|
|
1137
2155
|
}
|
|
1138
2156
|
];
|
|
1139
|
-
var cursorColor = cursorColors[
|
|
2157
|
+
var cursorColor = cursorColors[random2.uint32() % cursorColors.length];
|
|
1140
2158
|
|
|
1141
2159
|
// packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts
|
|
1142
2160
|
import * as decoding from "lib0/decoding";
|
|
@@ -1144,7 +2162,7 @@ import * as encoding from "lib0/encoding";
|
|
|
1144
2162
|
import { Observable } from "lib0/observable";
|
|
1145
2163
|
import * as awarenessProtocol from "y-protocols/awareness";
|
|
1146
2164
|
import { log } from "@dxos/log";
|
|
1147
|
-
var
|
|
2165
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts";
|
|
1148
2166
|
var messageAwareness = 1;
|
|
1149
2167
|
var messageQueryAwareness = 3;
|
|
1150
2168
|
var SpaceAwarenessProvider = class extends Observable {
|
|
@@ -1181,7 +2199,7 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1181
2199
|
removed,
|
|
1182
2200
|
origin
|
|
1183
2201
|
}, {
|
|
1184
|
-
F:
|
|
2202
|
+
F: __dxlog_file3,
|
|
1185
2203
|
L: 67,
|
|
1186
2204
|
S: this,
|
|
1187
2205
|
C: (f, a) => f(...a)
|
|
@@ -1194,7 +2212,7 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1194
2212
|
}
|
|
1195
2213
|
_handleSpaceMessage({ payload }) {
|
|
1196
2214
|
log("space message", payload, {
|
|
1197
|
-
F:
|
|
2215
|
+
F: __dxlog_file3,
|
|
1198
2216
|
L: 79,
|
|
1199
2217
|
S: this,
|
|
1200
2218
|
C: (f, a) => f(...a)
|
|
@@ -1239,14 +2257,14 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1239
2257
|
};
|
|
1240
2258
|
|
|
1241
2259
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
1242
|
-
var
|
|
2260
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
1243
2261
|
var useTextModel = ({ identity, space, text }) => {
|
|
1244
2262
|
const [model, setModel] = useState2(() => createModel({
|
|
1245
2263
|
identity,
|
|
1246
2264
|
space,
|
|
1247
2265
|
text
|
|
1248
2266
|
}));
|
|
1249
|
-
|
|
2267
|
+
useEffect3(() => {
|
|
1250
2268
|
setModel(createModel({
|
|
1251
2269
|
identity,
|
|
1252
2270
|
space,
|
|
@@ -1260,44 +2278,45 @@ var useTextModel = ({ identity, space, text }) => {
|
|
|
1260
2278
|
return model;
|
|
1261
2279
|
};
|
|
1262
2280
|
var createModel = (options) => {
|
|
1263
|
-
const {
|
|
2281
|
+
const { text } = options;
|
|
1264
2282
|
if (isActualAutomergeObject(text)) {
|
|
1265
2283
|
return createAutomergeModel(options);
|
|
1266
2284
|
} else {
|
|
1267
|
-
if (!
|
|
2285
|
+
if (!text?.doc) {
|
|
1268
2286
|
return void 0;
|
|
1269
2287
|
}
|
|
1270
2288
|
return createYjsModel(options);
|
|
1271
2289
|
}
|
|
1272
2290
|
};
|
|
1273
2291
|
var createYjsModel = ({ identity, space, text }) => {
|
|
1274
|
-
|
|
1275
|
-
F:
|
|
1276
|
-
L:
|
|
2292
|
+
invariant3(text?.doc && text?.content, void 0, {
|
|
2293
|
+
F: __dxlog_file4,
|
|
2294
|
+
L: 81,
|
|
1277
2295
|
S: void 0,
|
|
1278
2296
|
A: [
|
|
1279
|
-
"
|
|
2297
|
+
"text?.doc && text?.content",
|
|
1280
2298
|
""
|
|
1281
2299
|
]
|
|
1282
2300
|
});
|
|
1283
|
-
const provider = new SpaceAwarenessProvider({
|
|
2301
|
+
const provider = space ? new SpaceAwarenessProvider({
|
|
1284
2302
|
space,
|
|
1285
2303
|
doc: text.doc,
|
|
1286
2304
|
channel: `yjs.awareness.${text.id}`
|
|
1287
|
-
});
|
|
2305
|
+
}) : void 0;
|
|
1288
2306
|
return {
|
|
1289
2307
|
id: text.doc.guid,
|
|
1290
2308
|
content: text.content,
|
|
1291
2309
|
text: () => text.content.toString(),
|
|
1292
|
-
|
|
1293
|
-
|
|
2310
|
+
ranges: [],
|
|
2311
|
+
extension: yCollab(text.content, provider?.awareness),
|
|
2312
|
+
awareness: provider?.awareness,
|
|
1294
2313
|
peer: identity ? {
|
|
1295
2314
|
id: identity.identityKey.toHex(),
|
|
1296
2315
|
name: identity.profile?.displayName
|
|
1297
2316
|
} : void 0
|
|
1298
2317
|
};
|
|
1299
2318
|
};
|
|
1300
|
-
var createAutomergeModel = ({ identity,
|
|
2319
|
+
var createAutomergeModel = ({ identity, text }) => {
|
|
1301
2320
|
const obj = text;
|
|
1302
2321
|
const doc = getRawDoc(obj, [
|
|
1303
2322
|
obj.field
|
|
@@ -1305,7 +2324,8 @@ var createAutomergeModel = ({ identity, space, text }) => {
|
|
|
1305
2324
|
return {
|
|
1306
2325
|
id: obj.id,
|
|
1307
2326
|
content: doc,
|
|
1308
|
-
text: () =>
|
|
2327
|
+
text: () => get4(doc.handle.docSync(), doc.path),
|
|
2328
|
+
ranges: [],
|
|
1309
2329
|
extension: automergePlugin(doc.handle, doc.path),
|
|
1310
2330
|
peer: identity ? {
|
|
1311
2331
|
id: identity.identityKey.toHex(),
|
|
@@ -1325,23 +2345,35 @@ export {
|
|
|
1325
2345
|
YXmlFragment,
|
|
1326
2346
|
autocomplete,
|
|
1327
2347
|
basicBundle,
|
|
2348
|
+
blast,
|
|
2349
|
+
code2 as code,
|
|
1328
2350
|
codeTheme,
|
|
2351
|
+
comments,
|
|
1329
2352
|
cursorColor,
|
|
2353
|
+
defaultMarkdownSlots,
|
|
2354
|
+
defaultOptions,
|
|
1330
2355
|
defaultSlots,
|
|
1331
2356
|
defaultTextSlots,
|
|
1332
2357
|
defaultTheme,
|
|
2358
|
+
demo,
|
|
2359
|
+
highlight,
|
|
2360
|
+
highlightDecorations,
|
|
2361
|
+
highlightStateField,
|
|
2362
|
+
image,
|
|
1333
2363
|
link,
|
|
1334
|
-
listener,
|
|
2364
|
+
listener2 as listener,
|
|
1335
2365
|
markdownBundle,
|
|
1336
2366
|
markdownHighlightStyle,
|
|
1337
2367
|
markdownTags,
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
2368
|
+
markdownTagsExtensions,
|
|
2369
|
+
markdownTheme,
|
|
2370
|
+
mention,
|
|
2371
|
+
table,
|
|
1341
2372
|
tags2 as tags,
|
|
1342
2373
|
tasklist,
|
|
1343
2374
|
textTheme,
|
|
1344
2375
|
tooltip,
|
|
2376
|
+
useHighlights,
|
|
1345
2377
|
useTextModel
|
|
1346
2378
|
};
|
|
1347
2379
|
//# sourceMappingURL=index.mjs.map
|