@dxos/react-ui-editor 0.6.8-main.3be982f → 0.6.8-staging.63bcb81
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 +535 -521
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/TextEditor.stories.d.ts +5 -2
- package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/defaults.d.ts +2 -2
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/doc.d.ts +3 -0
- package/dist/types/src/extensions/doc.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts +2 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link-paste.d.ts +3 -0
- package/dist/types/src/extensions/markdown/link-paste.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +3 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/state.d.ts +14 -14
- package/dist/types/src/extensions/state.d.ts.map +1 -1
- package/dist/types/src/extensions/util/react.d.ts +1 -1
- package/dist/types/src/extensions/util/react.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +5 -3
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/markdown.d.ts +7 -17
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts +3 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/styles/tokens.d.ts +5 -7
- package/dist/types/src/styles/tokens.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/TextEditor.stories.tsx +40 -27
- package/src/defaults.ts +9 -2
- package/src/extensions/doc.ts +3 -0
- package/src/extensions/factories.ts +3 -2
- package/src/extensions/folding.tsx +5 -7
- package/src/extensions/markdown/bundle.ts +1 -3
- package/src/extensions/markdown/decorate.ts +31 -24
- package/src/extensions/markdown/formatting.ts +3 -1
- package/src/extensions/markdown/highlight.ts +33 -19
- package/src/extensions/markdown/link-paste.ts +3 -0
- package/src/extensions/state.ts +41 -35
- package/src/extensions/util/react.tsx +3 -4
- package/src/hooks/useTextEditor.ts +24 -29
- package/src/index.ts +2 -0
- package/src/styles/markdown.ts +17 -40
- package/src/styles/theme.ts +91 -86
- package/src/styles/tokens.ts +9 -7
|
@@ -37,6 +37,280 @@ import { keymap as keymap11 } from "@codemirror/view";
|
|
|
37
37
|
import { tags as tags2 } from "@lezer/highlight";
|
|
38
38
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
39
39
|
|
|
40
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
41
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
42
|
+
var headings = {
|
|
43
|
+
1: "text-4xl",
|
|
44
|
+
2: "text-3xl",
|
|
45
|
+
3: "text-2xl",
|
|
46
|
+
4: "text-xl",
|
|
47
|
+
5: "text-lg",
|
|
48
|
+
6: "text-md"
|
|
49
|
+
};
|
|
50
|
+
var theme = {
|
|
51
|
+
mark: "opacity-50",
|
|
52
|
+
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
|
53
|
+
codeMark: "font-mono text-primary-500",
|
|
54
|
+
// TODO(burdon): Replace with widget.
|
|
55
|
+
blockquote: "pl-1 mr-1 border-is-4 border-orange-500 dark:border-orange-500 dark:text-neutral-500",
|
|
56
|
+
heading: (level) => {
|
|
57
|
+
return mx(headings[level], "dark:text-primary-400");
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
62
|
+
import get from "lodash.get";
|
|
63
|
+
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
64
|
+
var tokens = tailwindConfig({}).theme;
|
|
65
|
+
var getToken = (path, defaultValue) => {
|
|
66
|
+
const value = get(tokens, path, defaultValue);
|
|
67
|
+
return value?.toString() ?? "";
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// packages/ui/react-ui-editor/src/styles/theme.ts
|
|
71
|
+
var defaultTheme = {
|
|
72
|
+
"&": {},
|
|
73
|
+
"&.cm-focused": {
|
|
74
|
+
outline: "none"
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* Scroller
|
|
78
|
+
*/
|
|
79
|
+
".cm-scroller": {
|
|
80
|
+
overflowY: "auto"
|
|
81
|
+
},
|
|
82
|
+
/**
|
|
83
|
+
* Content
|
|
84
|
+
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
|
85
|
+
*/
|
|
86
|
+
".cm-content": {
|
|
87
|
+
padding: "unset",
|
|
88
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
89
|
+
fontSize: "16px",
|
|
90
|
+
fontFamily: getToken("fontFamily.body"),
|
|
91
|
+
lineHeight: 1.5
|
|
92
|
+
},
|
|
93
|
+
"&light .cm-content": {
|
|
94
|
+
color: getToken("extend.semanticColors.base.fg.light", "black")
|
|
95
|
+
},
|
|
96
|
+
"&dark .cm-content": {
|
|
97
|
+
color: getToken("extend.semanticColors.base.fg.dark", "white")
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* Gutters
|
|
101
|
+
* NOTE: Gutters should have the same top margin as the content.
|
|
102
|
+
*/
|
|
103
|
+
".cm-gutters": {
|
|
104
|
+
background: "transparent"
|
|
105
|
+
},
|
|
106
|
+
".cm-gutter": {},
|
|
107
|
+
".cm-gutterElement": {
|
|
108
|
+
lineHeight: 1.5
|
|
109
|
+
},
|
|
110
|
+
//
|
|
111
|
+
// Cursor
|
|
112
|
+
//
|
|
113
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
114
|
+
borderLeft: "2px solid black"
|
|
115
|
+
},
|
|
116
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
117
|
+
borderLeft: "2px solid white"
|
|
118
|
+
},
|
|
119
|
+
"&light .cm-placeholder": {
|
|
120
|
+
color: getToken("extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
121
|
+
},
|
|
122
|
+
"&dark .cm-placeholder": {
|
|
123
|
+
color: getToken("extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
124
|
+
},
|
|
125
|
+
//
|
|
126
|
+
// line
|
|
127
|
+
//
|
|
128
|
+
".cm-line": {
|
|
129
|
+
paddingInline: 0
|
|
130
|
+
},
|
|
131
|
+
".cm-activeLine": {
|
|
132
|
+
background: "transparent"
|
|
133
|
+
},
|
|
134
|
+
//
|
|
135
|
+
// gutter
|
|
136
|
+
//
|
|
137
|
+
".cm-lineNumbers": {
|
|
138
|
+
minWidth: "36px"
|
|
139
|
+
},
|
|
140
|
+
//
|
|
141
|
+
// Selection
|
|
142
|
+
//
|
|
143
|
+
"&light .cm-selectionBackground": {
|
|
144
|
+
background: getToken("extend.colors.primary.100")
|
|
145
|
+
},
|
|
146
|
+
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
147
|
+
background: getToken("extend.colors.primary.200")
|
|
148
|
+
},
|
|
149
|
+
"&dark .cm-selectionBackground": {
|
|
150
|
+
background: getToken("extend.colors.primary.700")
|
|
151
|
+
},
|
|
152
|
+
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
153
|
+
background: getToken("extend.colors.primary.600")
|
|
154
|
+
},
|
|
155
|
+
//
|
|
156
|
+
// Search
|
|
157
|
+
//
|
|
158
|
+
"&light .cm-searchMatch": {
|
|
159
|
+
backgroundColor: getToken("extend.colors.yellow.100")
|
|
160
|
+
},
|
|
161
|
+
"&dark .cm-searchMatch": {
|
|
162
|
+
backgroundColor: getToken("extend.colors.yellow.700")
|
|
163
|
+
},
|
|
164
|
+
//
|
|
165
|
+
// link
|
|
166
|
+
//
|
|
167
|
+
".cm-link": {
|
|
168
|
+
textDecorationLine: "underline",
|
|
169
|
+
textDecorationThickness: "1px",
|
|
170
|
+
textUnderlineOffset: "2px",
|
|
171
|
+
borderRadius: ".125rem",
|
|
172
|
+
fontFamily: getToken("fontFamily.body")
|
|
173
|
+
},
|
|
174
|
+
"&light .cm-link > span": {
|
|
175
|
+
color: getToken("extend.colors.primary.600")
|
|
176
|
+
},
|
|
177
|
+
"&dark .cm-link > span": {
|
|
178
|
+
color: getToken("extend.colors.primary.400")
|
|
179
|
+
},
|
|
180
|
+
//
|
|
181
|
+
// tooltip
|
|
182
|
+
//
|
|
183
|
+
".cm-tooltip": {},
|
|
184
|
+
"&light .cm-tooltip": {
|
|
185
|
+
background: `${getToken("extend.colors.neutral.100")} !important`
|
|
186
|
+
},
|
|
187
|
+
"&dark .cm-tooltip": {
|
|
188
|
+
background: `${getToken("extend.colors.neutral.900")} !important`
|
|
189
|
+
},
|
|
190
|
+
".cm-tooltip-below": {},
|
|
191
|
+
//
|
|
192
|
+
// autocomplete
|
|
193
|
+
// https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
194
|
+
//
|
|
195
|
+
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
196
|
+
marginTop: "4px",
|
|
197
|
+
marginLeft: "-3px"
|
|
198
|
+
},
|
|
199
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
200
|
+
maxHeight: "20em !important"
|
|
201
|
+
},
|
|
202
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
|
203
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
|
204
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
205
|
+
paddingLeft: "4px !important",
|
|
206
|
+
borderBottom: "none !important",
|
|
207
|
+
color: getToken("extend.colors.primary.500")
|
|
208
|
+
},
|
|
209
|
+
".cm-tooltip.cm-completionInfo": {
|
|
210
|
+
border: getToken("extend.colors.neutral.500"),
|
|
211
|
+
width: "360px !important",
|
|
212
|
+
margin: "-10px 1px 0 1px",
|
|
213
|
+
padding: "8px !important"
|
|
214
|
+
},
|
|
215
|
+
".cm-completionIcon": {
|
|
216
|
+
display: "none"
|
|
217
|
+
},
|
|
218
|
+
".cm-completionLabel": {
|
|
219
|
+
fontFamily: getToken("fontFamily.body")
|
|
220
|
+
},
|
|
221
|
+
".cm-completionMatchedText": {
|
|
222
|
+
textDecoration: "none !important",
|
|
223
|
+
opacity: 0.5
|
|
224
|
+
},
|
|
225
|
+
// TODO(burdon): Override vars --cm-background.
|
|
226
|
+
// https://www.npmjs.com/package/codemirror-theme-vars
|
|
227
|
+
/**
|
|
228
|
+
* Panels
|
|
229
|
+
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
230
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
231
|
+
*
|
|
232
|
+
* Find/replace panel.
|
|
233
|
+
* <div class="cm-announced">...</div>
|
|
234
|
+
* <div class="cm-scroller">...</div>
|
|
235
|
+
* <div class="cm-panels cm-panels-bottom">
|
|
236
|
+
* <div class="cm-search cm-panel">
|
|
237
|
+
* <input class="cm-textfield" />
|
|
238
|
+
* <button class="cm-button">...</button>
|
|
239
|
+
* <label><input type="checkbox" />...</label>
|
|
240
|
+
* </div>
|
|
241
|
+
* </div
|
|
242
|
+
*/
|
|
243
|
+
".cm-panels": {},
|
|
244
|
+
".cm-panel": {
|
|
245
|
+
fontFamily: getToken("fontFamily.body")
|
|
246
|
+
},
|
|
247
|
+
".cm-panel input[type=checkbox]": {
|
|
248
|
+
marginRight: "0.4rem !important"
|
|
249
|
+
},
|
|
250
|
+
"&light .cm-panel": {
|
|
251
|
+
background: getToken("extend.colors.neutral.50")
|
|
252
|
+
},
|
|
253
|
+
"&dark .cm-panel": {
|
|
254
|
+
background: getToken("extend.colors.neutral.850")
|
|
255
|
+
},
|
|
256
|
+
".cm-button": {
|
|
257
|
+
margin: "4px",
|
|
258
|
+
fontFamily: getToken("fontFamily.body"),
|
|
259
|
+
backgroundImage: "none",
|
|
260
|
+
border: "none",
|
|
261
|
+
"&:active": {
|
|
262
|
+
backgroundImage: "none"
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"&light .cm-button": {
|
|
266
|
+
background: getToken("extend.colors.neutral.100"),
|
|
267
|
+
"&:hover": {
|
|
268
|
+
background: getToken("extend.colors.neutral.200")
|
|
269
|
+
},
|
|
270
|
+
"&:active": {
|
|
271
|
+
background: getToken("extend.colors.neutral.300")
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
"&dark .cm-button": {
|
|
275
|
+
background: getToken("extend.colors.neutral.800"),
|
|
276
|
+
"&:hover": {
|
|
277
|
+
background: getToken("extend.colors.neutral.700")
|
|
278
|
+
},
|
|
279
|
+
"&:active": {
|
|
280
|
+
background: getToken("extend.colors.neutral.600")
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
// TODO(burdon): Factor out element specific logic.
|
|
284
|
+
//
|
|
285
|
+
// table
|
|
286
|
+
//
|
|
287
|
+
".cm-table *": {
|
|
288
|
+
fontFamily: `${getToken("fontFamily.mono")} !important`,
|
|
289
|
+
textDecoration: "none !important"
|
|
290
|
+
},
|
|
291
|
+
".cm-table-head": {
|
|
292
|
+
padding: "2px 16px 2px 0px",
|
|
293
|
+
textAlign: "left",
|
|
294
|
+
borderBottom: `1px solid ${getToken("extend.colors.primary.500")}`,
|
|
295
|
+
color: getToken("extend.colors.neutral.500")
|
|
296
|
+
},
|
|
297
|
+
".cm-table-cell": {
|
|
298
|
+
padding: "2px 16px 2px 0px"
|
|
299
|
+
},
|
|
300
|
+
//
|
|
301
|
+
// image
|
|
302
|
+
//
|
|
303
|
+
".cm-image": {
|
|
304
|
+
display: "block",
|
|
305
|
+
height: "0"
|
|
306
|
+
},
|
|
307
|
+
".cm-image.cm-loaded-image": {
|
|
308
|
+
height: "auto",
|
|
309
|
+
borderTop: "0.5rem solid transparent",
|
|
310
|
+
borderBottom: "0.5rem solid transparent"
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
40
314
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
41
315
|
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
|
|
42
316
|
import { createContext } from "@radix-ui/react-context";
|
|
@@ -1365,309 +1639,33 @@ import { nonNullable } from "@dxos/util";
|
|
|
1365
1639
|
import { log as log3 } from "@dxos/log";
|
|
1366
1640
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/util/error.ts";
|
|
1367
1641
|
var wrapWithCatch = (fn) => {
|
|
1368
|
-
return (...args) => {
|
|
1369
|
-
try {
|
|
1370
|
-
return fn(...args);
|
|
1371
|
-
} catch (err) {
|
|
1372
|
-
log3.catch(err, void 0, {
|
|
1373
|
-
F: __dxlog_file5,
|
|
1374
|
-
L: 12,
|
|
1375
|
-
S: void 0,
|
|
1376
|
-
C: (f, a) => f(...a)
|
|
1377
|
-
});
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
};
|
|
1381
|
-
|
|
1382
|
-
// packages/ui/react-ui-editor/src/extensions/util/overlap.ts
|
|
1383
|
-
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
1384
|
-
|
|
1385
|
-
// packages/ui/react-ui-editor/src/extensions/util/react.tsx
|
|
1386
|
-
import React from "react";
|
|
1387
|
-
import { createRoot } from "react-dom/client";
|
|
1388
|
-
import { ThemeProvider } from "@dxos/react-ui";
|
|
1389
|
-
import { defaultTx } from "@dxos/react-ui-theme";
|
|
1390
|
-
var renderRoot = (node) => {
|
|
1391
|
-
const el = document.createElement("div");
|
|
1392
|
-
createRoot(el).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
|
|
1393
|
-
tx: defaultTx
|
|
1394
|
-
}, node));
|
|
1395
|
-
return el;
|
|
1396
|
-
};
|
|
1397
|
-
|
|
1398
|
-
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
1399
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
1400
|
-
var headings = {
|
|
1401
|
-
1: "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
1402
|
-
2: "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
1403
|
-
3: "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
1404
|
-
4: "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
1405
|
-
5: "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
1406
|
-
6: "mbs-4 mbe-2 font-medium text-inherit no-underline"
|
|
1407
|
-
};
|
|
1408
|
-
var heading = (level) => {
|
|
1409
|
-
return mx(headings[level], "dark:text-primary-400");
|
|
1410
|
-
};
|
|
1411
|
-
var light = "text-neutral-200 dark:text-neutral-800";
|
|
1412
|
-
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
1413
|
-
var bold = "font-bold";
|
|
1414
|
-
var italic = "italic";
|
|
1415
|
-
var strikethrough = "line-through";
|
|
1416
|
-
var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
|
|
1417
|
-
var codeMark = "font-mono text-primary-500";
|
|
1418
|
-
var inlineUrl = mx(code, "px-1");
|
|
1419
|
-
var blockquote = mx("pl-1 mr-1 border-is-4 border-orange-500 dark:border-orange-500 text-transparent");
|
|
1420
|
-
|
|
1421
|
-
// packages/ui/react-ui-editor/src/styles/theme.ts
|
|
1422
|
-
import get2 from "lodash.get";
|
|
1423
|
-
|
|
1424
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
1425
|
-
import get from "lodash.get";
|
|
1426
|
-
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
1427
|
-
var tokens = tailwindConfig({}).theme;
|
|
1428
|
-
var getToken = (path, defaultValue = void 0) => get(tokens, path, defaultValue);
|
|
1429
|
-
|
|
1430
|
-
// packages/ui/react-ui-editor/src/styles/theme.ts
|
|
1431
|
-
var defaultTheme = {
|
|
1432
|
-
"&": {},
|
|
1433
|
-
"&.cm-focused": {
|
|
1434
|
-
outline: "none"
|
|
1435
|
-
},
|
|
1436
|
-
// Scroller.
|
|
1437
|
-
// NOTE: See https://codemirror.net/docs/guide (DOM Structure).
|
|
1438
|
-
".cm-scroller": {
|
|
1439
|
-
overflowY: "auto",
|
|
1440
|
-
fontFamily: get2(tokens, "fontFamily.body", []).join(","),
|
|
1441
|
-
lineHeight: 1.5
|
|
1442
|
-
},
|
|
1443
|
-
// Content.
|
|
1444
|
-
".cm-content": {
|
|
1445
|
-
padding: "unset",
|
|
1446
|
-
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
1447
|
-
fontSize: "16px"
|
|
1448
|
-
},
|
|
1449
|
-
"&light .cm-content": {
|
|
1450
|
-
color: get2(tokens, "extend.semanticColors.base.fg.light", "black")
|
|
1451
|
-
},
|
|
1452
|
-
"&dark .cm-content": {
|
|
1453
|
-
color: get2(tokens, "extend.semanticColors.base.fg.dark", "red")
|
|
1454
|
-
},
|
|
1455
|
-
//
|
|
1456
|
-
// Cursor
|
|
1457
|
-
//
|
|
1458
|
-
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
1459
|
-
borderLeft: "2px solid black"
|
|
1460
|
-
},
|
|
1461
|
-
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
1462
|
-
borderLeft: "2px solid white"
|
|
1463
|
-
},
|
|
1464
|
-
"&light .cm-placeholder": {
|
|
1465
|
-
color: get2(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
1466
|
-
},
|
|
1467
|
-
"&dark .cm-placeholder": {
|
|
1468
|
-
color: get2(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
1469
|
-
},
|
|
1470
|
-
//
|
|
1471
|
-
// line
|
|
1472
|
-
//
|
|
1473
|
-
".cm-line": {
|
|
1474
|
-
paddingInline: 0
|
|
1475
|
-
},
|
|
1476
|
-
".cm-activeLine": {
|
|
1477
|
-
background: "transparent"
|
|
1478
|
-
},
|
|
1479
|
-
//
|
|
1480
|
-
// gutter
|
|
1481
|
-
//
|
|
1482
|
-
".cm-lineNumbers": {
|
|
1483
|
-
minWidth: "36px"
|
|
1484
|
-
},
|
|
1485
|
-
//
|
|
1486
|
-
// Selection
|
|
1487
|
-
//
|
|
1488
|
-
"&light .cm-selectionBackground": {
|
|
1489
|
-
background: get2(tokens, "extend.colors.primary.100")
|
|
1490
|
-
},
|
|
1491
|
-
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
1492
|
-
background: get2(tokens, "extend.colors.primary.200")
|
|
1493
|
-
},
|
|
1494
|
-
"&dark .cm-selectionBackground": {
|
|
1495
|
-
background: get2(tokens, "extend.colors.primary.700")
|
|
1496
|
-
},
|
|
1497
|
-
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
1498
|
-
background: get2(tokens, "extend.colors.primary.600")
|
|
1499
|
-
},
|
|
1500
|
-
//
|
|
1501
|
-
// Search
|
|
1502
|
-
//
|
|
1503
|
-
"&light .cm-searchMatch": {
|
|
1504
|
-
backgroundColor: get2(tokens, "extend.colors.yellow.100")
|
|
1505
|
-
},
|
|
1506
|
-
"&dark .cm-searchMatch": {
|
|
1507
|
-
backgroundColor: get2(tokens, "extend.colors.yellow.700")
|
|
1508
|
-
},
|
|
1509
|
-
//
|
|
1510
|
-
// link
|
|
1511
|
-
//
|
|
1512
|
-
".cm-link": {
|
|
1513
|
-
color: get2(tokens, "extend.colors.primary.500"),
|
|
1514
|
-
textDecorationLine: "underline",
|
|
1515
|
-
textDecorationThickness: "1px",
|
|
1516
|
-
textUnderlineOffset: "2px",
|
|
1517
|
-
borderRadius: ".125rem",
|
|
1518
|
-
fontFamily: get2(tokens, "fontFamily.body", []).join(",")
|
|
1519
|
-
},
|
|
1520
|
-
//
|
|
1521
|
-
// tooltip
|
|
1522
|
-
//
|
|
1523
|
-
".cm-tooltip": {},
|
|
1524
|
-
"&light .cm-tooltip": {
|
|
1525
|
-
background: `${get2(tokens, "extend.colors.neutral.100")} !important`
|
|
1526
|
-
},
|
|
1527
|
-
"&dark .cm-tooltip": {
|
|
1528
|
-
background: `${get2(tokens, "extend.colors.neutral.900")} !important`
|
|
1529
|
-
},
|
|
1530
|
-
".cm-tooltip-below": {},
|
|
1531
|
-
//
|
|
1532
|
-
// autocomplete
|
|
1533
|
-
// https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
1534
|
-
//
|
|
1535
|
-
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
1536
|
-
marginTop: "4px",
|
|
1537
|
-
marginLeft: "-3px"
|
|
1538
|
-
},
|
|
1539
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
1540
|
-
maxHeight: "20em !important"
|
|
1541
|
-
},
|
|
1542
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
|
1543
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
|
1544
|
-
// TODO(burdon): Can we add a class prefix to avoid adding !important?
|
|
1545
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
1546
|
-
paddingLeft: "4px !important",
|
|
1547
|
-
borderBottom: "none !important",
|
|
1548
|
-
color: get2(tokens, "extend.colors.primary.500")
|
|
1549
|
-
},
|
|
1550
|
-
".cm-tooltip.cm-completionInfo": {
|
|
1551
|
-
border: get2(tokens, "extend.colors.neutral.500"),
|
|
1552
|
-
width: "360px !important",
|
|
1553
|
-
margin: "-10px 1px 0 1px",
|
|
1554
|
-
padding: "8px !important"
|
|
1555
|
-
},
|
|
1556
|
-
".cm-completionIcon": {
|
|
1557
|
-
display: "none"
|
|
1558
|
-
},
|
|
1559
|
-
".cm-completionLabel": {
|
|
1560
|
-
fontFamily: get2(tokens, "fontFamily.body", []).join(",")
|
|
1561
|
-
},
|
|
1562
|
-
".cm-completionMatchedText": {
|
|
1563
|
-
textDecoration: "none !important",
|
|
1564
|
-
opacity: 0.5
|
|
1565
|
-
},
|
|
1566
|
-
//
|
|
1567
|
-
// table
|
|
1568
|
-
//
|
|
1569
|
-
".cm-table *": {
|
|
1570
|
-
fontFamily: `${get2(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
1571
|
-
textDecoration: "none !important"
|
|
1572
|
-
},
|
|
1573
|
-
".cm-table-head": {
|
|
1574
|
-
padding: "2px 16px 2px 0px",
|
|
1575
|
-
textAlign: "left",
|
|
1576
|
-
borderBottom: `1px solid ${get2(tokens, "extend.colors.primary.500")}`,
|
|
1577
|
-
color: get2(tokens, "extend.colors.neutral.500")
|
|
1578
|
-
},
|
|
1579
|
-
".cm-table-cell": {
|
|
1580
|
-
padding: "2px 16px 2px 0px"
|
|
1581
|
-
},
|
|
1582
|
-
//
|
|
1583
|
-
// image
|
|
1584
|
-
//
|
|
1585
|
-
".cm-image": {
|
|
1586
|
-
display: "block",
|
|
1587
|
-
height: "0"
|
|
1588
|
-
},
|
|
1589
|
-
".cm-image.cm-loaded-image": {
|
|
1590
|
-
height: "auto",
|
|
1591
|
-
borderTop: "0.5rem solid transparent",
|
|
1592
|
-
borderBottom: "0.5rem solid transparent"
|
|
1593
|
-
},
|
|
1594
|
-
//
|
|
1595
|
-
// font size
|
|
1596
|
-
// TODO(thure): This appears to be the best or only way to set selection caret heights,
|
|
1597
|
-
// but it's far more verbose than it needs to be.
|
|
1598
|
-
//
|
|
1599
|
-
// ...Object.keys(get(tokens, 'extend.fontSize', {})).reduce((acc: Record<string, any>, fontSize) => {
|
|
1600
|
-
// const height = get(tokens, ['extend', 'fontSize', fontSize, 1, 'lineHeight']);
|
|
1601
|
-
//
|
|
1602
|
-
// acc[`& .text-${fontSize} + .cm-ySelectionCaret`] = { height };
|
|
1603
|
-
// acc[`& .text-${fontSize} + .cm-ySelection + .cm-ySelectionCaret`] = { height };
|
|
1604
|
-
// acc[`& .text-${fontSize} + .cm-widgetBuffer + .cm-ySelectionCaret`] = { height };
|
|
1605
|
-
// return acc;
|
|
1606
|
-
// }, {}),
|
|
1607
|
-
// TODO(burdon): Override vars --cm-background.
|
|
1608
|
-
// https://www.npmjs.com/package/codemirror-theme-vars
|
|
1609
|
-
/**
|
|
1610
|
-
* Gutters
|
|
1611
|
-
*/
|
|
1612
|
-
".cm-gutters": {
|
|
1613
|
-
background: "transparent"
|
|
1614
|
-
},
|
|
1615
|
-
/**
|
|
1616
|
-
* Panels
|
|
1617
|
-
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
1618
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
1619
|
-
*
|
|
1620
|
-
* Find/replace panel.
|
|
1621
|
-
* <div class="cm-announced">...</div>
|
|
1622
|
-
* <div class="cm-scroller">...</div>
|
|
1623
|
-
* <div class="cm-panels cm-panels-bottom">
|
|
1624
|
-
* <div class="cm-search cm-panel">
|
|
1625
|
-
* <input class="cm-textfield" />
|
|
1626
|
-
* <button class="cm-button">...</button>
|
|
1627
|
-
* <label><input type="checkbox" />...</label>
|
|
1628
|
-
* </div>
|
|
1629
|
-
* </div
|
|
1630
|
-
*/
|
|
1631
|
-
".cm-panels": {},
|
|
1632
|
-
".cm-panel": {
|
|
1633
|
-
fontFamily: get2(tokens, "fontFamily.body", []).join(",")
|
|
1634
|
-
},
|
|
1635
|
-
".cm-panel input[type=checkbox]": {
|
|
1636
|
-
marginRight: "0.4rem !important"
|
|
1637
|
-
},
|
|
1638
|
-
"&light .cm-panel": {
|
|
1639
|
-
background: get2(tokens, "extend.colors.neutral.50")
|
|
1640
|
-
},
|
|
1641
|
-
"&dark .cm-panel": {
|
|
1642
|
-
background: get2(tokens, "extend.colors.neutral.850")
|
|
1643
|
-
},
|
|
1644
|
-
".cm-button": {
|
|
1645
|
-
margin: "4px",
|
|
1646
|
-
fontFamily: get2(tokens, "fontFamily.body", []).join(","),
|
|
1647
|
-
backgroundImage: "none",
|
|
1648
|
-
border: "none",
|
|
1649
|
-
"&:active": {
|
|
1650
|
-
backgroundImage: "none"
|
|
1651
|
-
}
|
|
1652
|
-
},
|
|
1653
|
-
"&light .cm-button": {
|
|
1654
|
-
background: get2(tokens, "extend.colors.neutral.100"),
|
|
1655
|
-
"&:hover": {
|
|
1656
|
-
background: get2(tokens, "extend.colors.neutral.200")
|
|
1657
|
-
},
|
|
1658
|
-
"&:active": {
|
|
1659
|
-
background: get2(tokens, "extend.colors.neutral.300")
|
|
1660
|
-
}
|
|
1661
|
-
},
|
|
1662
|
-
"&dark .cm-button": {
|
|
1663
|
-
background: get2(tokens, "extend.colors.neutral.800"),
|
|
1664
|
-
"&:hover": {
|
|
1665
|
-
background: get2(tokens, "extend.colors.neutral.700")
|
|
1666
|
-
},
|
|
1667
|
-
"&:active": {
|
|
1668
|
-
background: get2(tokens, "extend.colors.neutral.600")
|
|
1642
|
+
return (...args) => {
|
|
1643
|
+
try {
|
|
1644
|
+
return fn(...args);
|
|
1645
|
+
} catch (err) {
|
|
1646
|
+
log3.catch(err, void 0, {
|
|
1647
|
+
F: __dxlog_file5,
|
|
1648
|
+
L: 12,
|
|
1649
|
+
S: void 0,
|
|
1650
|
+
C: (f, a) => f(...a)
|
|
1651
|
+
});
|
|
1669
1652
|
}
|
|
1670
|
-
}
|
|
1653
|
+
};
|
|
1654
|
+
};
|
|
1655
|
+
|
|
1656
|
+
// packages/ui/react-ui-editor/src/extensions/util/overlap.ts
|
|
1657
|
+
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
1658
|
+
|
|
1659
|
+
// packages/ui/react-ui-editor/src/extensions/util/react.tsx
|
|
1660
|
+
import React from "react";
|
|
1661
|
+
import { createRoot } from "react-dom/client";
|
|
1662
|
+
import { ThemeProvider } from "@dxos/react-ui";
|
|
1663
|
+
import { defaultTx } from "@dxos/react-ui-theme";
|
|
1664
|
+
var renderRoot = (root, node) => {
|
|
1665
|
+
createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
|
|
1666
|
+
tx: defaultTx
|
|
1667
|
+
}, node));
|
|
1668
|
+
return root;
|
|
1671
1669
|
};
|
|
1672
1670
|
|
|
1673
1671
|
// packages/ui/react-ui-editor/src/util.ts
|
|
@@ -1828,8 +1826,8 @@ var commentsDecorations = EditorView7.decorations.compute([
|
|
|
1828
1826
|
} else if (range.from === range.to) {
|
|
1829
1827
|
return void 0;
|
|
1830
1828
|
}
|
|
1831
|
-
const
|
|
1832
|
-
return
|
|
1829
|
+
const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
|
|
1830
|
+
return mark.range(range.from, range.to);
|
|
1833
1831
|
}).filter(nonNullable);
|
|
1834
1832
|
return Decoration4.set(decorations);
|
|
1835
1833
|
});
|
|
@@ -2248,7 +2246,7 @@ var documentId2 = Facet5.define({
|
|
|
2248
2246
|
combine: (providers) => {
|
|
2249
2247
|
invariant3(providers.length <= 1, void 0, {
|
|
2250
2248
|
F: __dxlog_file8,
|
|
2251
|
-
L:
|
|
2249
|
+
L: 14,
|
|
2252
2250
|
S: void 0,
|
|
2253
2251
|
A: [
|
|
2254
2252
|
"providers.length <= 1",
|
|
@@ -2297,7 +2295,7 @@ var dropFile = (options = {}) => {
|
|
|
2297
2295
|
|
|
2298
2296
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
2299
2297
|
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
2300
|
-
import { defaultKeymap, history, historyKeymap,
|
|
2298
|
+
import { defaultKeymap, history, historyKeymap, standardKeymap } from "@codemirror/commands";
|
|
2301
2299
|
import { bracketMatching } from "@codemirror/language";
|
|
2302
2300
|
import { searchKeymap } from "@codemirror/search";
|
|
2303
2301
|
import { EditorState } from "@codemirror/state";
|
|
@@ -2357,10 +2355,9 @@ var createBasicExtensions = (_props) => {
|
|
|
2357
2355
|
// https://codemirror.net/docs/ref/#view.KeyBinding
|
|
2358
2356
|
keymap5.of([
|
|
2359
2357
|
...(props.keymap && keymaps[props.keymap]) ?? [],
|
|
2358
|
+
// NOTE: Tab configured by markdown extension.
|
|
2360
2359
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2361
|
-
...props.indentWithTab ? [
|
|
2362
|
-
indentWithTab
|
|
2363
|
-
] : [],
|
|
2360
|
+
// ...(props.indentWithTab ? [indentWithTab] : []),
|
|
2364
2361
|
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
2365
2362
|
...props.closeBrackets ? closeBracketsKeymap : [],
|
|
2366
2363
|
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
@@ -2375,12 +2372,12 @@ var defaultThemeSlots = {
|
|
|
2375
2372
|
className: "w-full bs-full"
|
|
2376
2373
|
}
|
|
2377
2374
|
};
|
|
2378
|
-
var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
|
|
2375
|
+
var createThemeExtensions = ({ theme: theme2, themeMode, slots: _slots } = {}) => {
|
|
2379
2376
|
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
|
2380
2377
|
return [
|
|
2381
2378
|
EditorView9.baseTheme(defaultTheme),
|
|
2382
2379
|
EditorView9.darkTheme.of(themeMode === "dark"),
|
|
2383
|
-
|
|
2380
|
+
theme2 && EditorView9.theme(theme2),
|
|
2384
2381
|
slots.editor?.className && EditorView9.editorAttributes.of({
|
|
2385
2382
|
class: slots.editor.className
|
|
2386
2383
|
}),
|
|
@@ -2414,21 +2411,18 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
|
2414
2411
|
// packages/ui/react-ui-editor/src/extensions/folding.tsx
|
|
2415
2412
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2416
2413
|
import React2 from "react";
|
|
2417
|
-
import {
|
|
2418
|
-
import { defaultTx as defaultTx2, getSize, mx as mx2 } from "@dxos/react-ui-theme";
|
|
2414
|
+
import { getSize, mx as mx2 } from "@dxos/react-ui-theme";
|
|
2419
2415
|
var folding = (_props = {}) => [
|
|
2420
2416
|
codeFolding({
|
|
2421
2417
|
placeholderDOM: () => document.createElement("div")
|
|
2422
2418
|
}),
|
|
2423
2419
|
foldGutter({
|
|
2424
2420
|
markerDOM: (open) => {
|
|
2425
|
-
return renderRoot(/* @__PURE__ */ React2.createElement(
|
|
2426
|
-
tx: defaultTx2
|
|
2427
|
-
}, /* @__PURE__ */ React2.createElement("svg", {
|
|
2421
|
+
return renderRoot(document.createElement("div"), /* @__PURE__ */ React2.createElement("svg", {
|
|
2428
2422
|
className: mx2(getSize(3), "m-3 cursor-pointer", open && "rotate-90")
|
|
2429
2423
|
}, /* @__PURE__ */ React2.createElement("use", {
|
|
2430
2424
|
href: "/icons.svg#ph--caret-right--regular"
|
|
2431
|
-
})))
|
|
2425
|
+
})));
|
|
2432
2426
|
}
|
|
2433
2427
|
})
|
|
2434
2428
|
];
|
|
@@ -2449,6 +2443,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
2449
2443
|
|
|
2450
2444
|
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
2451
2445
|
import { snippet } from "@codemirror/autocomplete";
|
|
2446
|
+
import { indentWithTab } from "@codemirror/commands";
|
|
2452
2447
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2453
2448
|
import { EditorSelection } from "@codemirror/state";
|
|
2454
2449
|
import { EditorView as EditorView11, keymap as keymap6 } from "@codemirror/view";
|
|
@@ -2870,28 +2865,28 @@ var addLink = ({ url, image: image2 } = {}) => {
|
|
|
2870
2865
|
let cursorOffset = 1;
|
|
2871
2866
|
for (const style of cutStyles) {
|
|
2872
2867
|
const type = InlineMarker[style.name];
|
|
2873
|
-
const
|
|
2868
|
+
const mark = inlineMarkerText(type);
|
|
2874
2869
|
if (style.from < from) {
|
|
2875
2870
|
changes2.push({
|
|
2876
2871
|
from: skipSpaces(from, state2.doc, -1),
|
|
2877
|
-
insert:
|
|
2872
|
+
insert: mark
|
|
2878
2873
|
});
|
|
2879
2874
|
changesAfter.push({
|
|
2880
2875
|
from: skipSpaces(from, state2.doc, 1, to),
|
|
2881
|
-
insert:
|
|
2876
|
+
insert: mark
|
|
2882
2877
|
});
|
|
2883
2878
|
} else {
|
|
2884
2879
|
changes2.push({
|
|
2885
2880
|
from: skipSpaces(to, state2.doc, -1, from),
|
|
2886
|
-
insert:
|
|
2881
|
+
insert: mark
|
|
2887
2882
|
});
|
|
2888
2883
|
const after = skipSpaces(to, state2.doc, 1);
|
|
2889
2884
|
if (after === to) {
|
|
2890
|
-
cursorOffset +=
|
|
2885
|
+
cursorOffset += mark.length;
|
|
2891
2886
|
}
|
|
2892
2887
|
changesAfter.push({
|
|
2893
2888
|
from: after,
|
|
2894
|
-
insert:
|
|
2889
|
+
insert: mark
|
|
2895
2890
|
});
|
|
2896
2891
|
}
|
|
2897
2892
|
}
|
|
@@ -2942,10 +2937,10 @@ var addList = (type) => {
|
|
|
2942
2937
|
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
2943
2938
|
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
2944
2939
|
if (type === 0) {
|
|
2945
|
-
const
|
|
2946
|
-
if (
|
|
2947
|
-
parentColumn +=
|
|
2948
|
-
counter = +
|
|
2940
|
+
const mark = /^\s*(\d+)[.)]/.exec(itemText);
|
|
2941
|
+
if (mark) {
|
|
2942
|
+
parentColumn += mark[1].length;
|
|
2943
|
+
counter = +mark[1] + 1;
|
|
2949
2944
|
}
|
|
2950
2945
|
}
|
|
2951
2946
|
}
|
|
@@ -3006,7 +3001,7 @@ var addList = (type) => {
|
|
|
3006
3001
|
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
3007
3002
|
padding = Math.max(padding, parentColumn2 - column);
|
|
3008
3003
|
}
|
|
3009
|
-
let
|
|
3004
|
+
let mark;
|
|
3010
3005
|
if (type === 0) {
|
|
3011
3006
|
let max = counter2;
|
|
3012
3007
|
for (let j = i + 1; j < blocks.length; j++) {
|
|
@@ -3017,20 +3012,20 @@ var addList = (type) => {
|
|
|
3017
3012
|
}
|
|
3018
3013
|
const num = String(counter2);
|
|
3019
3014
|
padding = Math.max(String(max).length, padding);
|
|
3020
|
-
|
|
3015
|
+
mark = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
|
|
3021
3016
|
} else {
|
|
3022
|
-
|
|
3017
|
+
mark = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
|
|
3023
3018
|
}
|
|
3024
3019
|
changes.push({
|
|
3025
3020
|
from: nodeFrom,
|
|
3026
|
-
insert:
|
|
3021
|
+
insert: mark
|
|
3027
3022
|
});
|
|
3028
3023
|
while (line.to < node.to) {
|
|
3029
3024
|
line = state2.doc.lineAt(line.to + 1);
|
|
3030
3025
|
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3031
3026
|
changes.push({
|
|
3032
3027
|
from: line.from + Math.min(open, column),
|
|
3033
|
-
insert: " ".repeat(
|
|
3028
|
+
insert: " ".repeat(mark.length)
|
|
3034
3029
|
});
|
|
3035
3030
|
}
|
|
3036
3031
|
}
|
|
@@ -3079,14 +3074,14 @@ var removeList = (type) => {
|
|
|
3079
3074
|
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
3080
3075
|
lastBlock = node.from;
|
|
3081
3076
|
let line = state2.doc.lineAt(node.from);
|
|
3082
|
-
const
|
|
3083
|
-
if (!
|
|
3077
|
+
const mark = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
3078
|
+
if (!mark) {
|
|
3084
3079
|
return false;
|
|
3085
3080
|
}
|
|
3086
3081
|
const column = node.from - line.from;
|
|
3087
3082
|
changes.push({
|
|
3088
3083
|
from: node.from,
|
|
3089
|
-
to: node.from +
|
|
3084
|
+
to: node.from + mark[0].length
|
|
3090
3085
|
});
|
|
3091
3086
|
while (line.to < node.to) {
|
|
3092
3087
|
line = state2.doc.lineAt(line.to + 1);
|
|
@@ -3094,7 +3089,7 @@ var removeList = (type) => {
|
|
|
3094
3089
|
if (open > column) {
|
|
3095
3090
|
changes.push({
|
|
3096
3091
|
from: line.from + column,
|
|
3097
|
-
to: line.from + Math.min(column +
|
|
3092
|
+
to: line.from + Math.min(column + mark[0].length, open)
|
|
3098
3093
|
});
|
|
3099
3094
|
}
|
|
3100
3095
|
}
|
|
@@ -3337,7 +3332,7 @@ var removeCodeblock = ({ state: state2, dispatch }) => {
|
|
|
3337
3332
|
var toggleCodeblock = (target) => {
|
|
3338
3333
|
return (getFormatting(target.state).blockType === "codeblock" ? removeCodeblock : addCodeblock)(target);
|
|
3339
3334
|
};
|
|
3340
|
-
var formattingKeymap = (
|
|
3335
|
+
var formattingKeymap = (_options = {}) => {
|
|
3341
3336
|
return [
|
|
3342
3337
|
keymap6.of([
|
|
3343
3338
|
{
|
|
@@ -3441,10 +3436,10 @@ var getFormatting = (state2) => {
|
|
|
3441
3436
|
}
|
|
3442
3437
|
}
|
|
3443
3438
|
for (let i = 0; i < inline.length; i++) {
|
|
3444
|
-
const
|
|
3445
|
-
const found = contextAfter.indexOf(
|
|
3439
|
+
const mark = inlineMarkerText(i);
|
|
3440
|
+
const found = contextAfter.indexOf(mark);
|
|
3446
3441
|
if (found > -1) {
|
|
3447
|
-
contextAfter = contextAfter.slice(0, found) + contextAfter.slice(found +
|
|
3442
|
+
contextAfter = contextAfter.slice(0, found) + contextAfter.slice(found + mark.length);
|
|
3448
3443
|
if (inline[i] === null) {
|
|
3449
3444
|
inline[i] = true;
|
|
3450
3445
|
}
|
|
@@ -3653,7 +3648,7 @@ var markdownTagsExtensions = [
|
|
|
3653
3648
|
]
|
|
3654
3649
|
}
|
|
3655
3650
|
];
|
|
3656
|
-
var markdownHighlightStyle = (
|
|
3651
|
+
var markdownHighlightStyle = (_options = {}) => {
|
|
3657
3652
|
return HighlightStyle.define([
|
|
3658
3653
|
{
|
|
3659
3654
|
tag: [
|
|
@@ -3691,6 +3686,7 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
3691
3686
|
tags.inserted,
|
|
3692
3687
|
tags.invalid
|
|
3693
3688
|
],
|
|
3689
|
+
// TODO(burdon): Explain.
|
|
3694
3690
|
color: "inherit !important"
|
|
3695
3691
|
},
|
|
3696
3692
|
// Markdown marks.
|
|
@@ -3702,26 +3698,29 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
3702
3698
|
markdownTags.LinkReference,
|
|
3703
3699
|
markdownTags.ListMark
|
|
3704
3700
|
],
|
|
3705
|
-
class: mark
|
|
3701
|
+
class: theme.mark
|
|
3706
3702
|
},
|
|
3707
3703
|
// Markdown marks.
|
|
3708
3704
|
{
|
|
3709
3705
|
tag: [
|
|
3706
|
+
//
|
|
3710
3707
|
markdownTags.CodeMark,
|
|
3711
3708
|
markdownTags.HeaderMark,
|
|
3712
3709
|
markdownTags.QuoteMark,
|
|
3713
3710
|
markdownTags.EmphasisMark
|
|
3714
3711
|
],
|
|
3715
|
-
class: mark
|
|
3712
|
+
class: theme.mark
|
|
3716
3713
|
},
|
|
3717
3714
|
// E.g., code block language (after ```).
|
|
3718
3715
|
{
|
|
3719
3716
|
tag: [
|
|
3717
|
+
//
|
|
3720
3718
|
tags.function(tags.variableName),
|
|
3721
3719
|
tags.labelName
|
|
3722
3720
|
],
|
|
3723
|
-
class: codeMark
|
|
3721
|
+
class: theme.codeMark
|
|
3724
3722
|
},
|
|
3723
|
+
// Fonts.
|
|
3725
3724
|
{
|
|
3726
3725
|
tag: [
|
|
3727
3726
|
tags.monospace
|
|
@@ -3731,40 +3730,40 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
3731
3730
|
// Headings.
|
|
3732
3731
|
{
|
|
3733
3732
|
tag: tags.heading1,
|
|
3734
|
-
class: heading(1)
|
|
3733
|
+
class: theme.heading(1)
|
|
3735
3734
|
},
|
|
3736
3735
|
{
|
|
3737
3736
|
tag: tags.heading2,
|
|
3738
|
-
class: heading(2)
|
|
3737
|
+
class: theme.heading(2)
|
|
3739
3738
|
},
|
|
3740
3739
|
{
|
|
3741
3740
|
tag: tags.heading3,
|
|
3742
|
-
class: heading(3)
|
|
3741
|
+
class: theme.heading(3)
|
|
3743
3742
|
},
|
|
3744
3743
|
{
|
|
3745
3744
|
tag: tags.heading4,
|
|
3746
|
-
class: heading(4)
|
|
3745
|
+
class: theme.heading(4)
|
|
3747
3746
|
},
|
|
3748
3747
|
{
|
|
3749
3748
|
tag: tags.heading5,
|
|
3750
|
-
class: heading(5)
|
|
3749
|
+
class: theme.heading(5)
|
|
3751
3750
|
},
|
|
3752
3751
|
{
|
|
3753
3752
|
tag: tags.heading6,
|
|
3754
|
-
class: heading(6)
|
|
3753
|
+
class: theme.heading(6)
|
|
3755
3754
|
},
|
|
3756
3755
|
// Emphasis.
|
|
3757
3756
|
{
|
|
3758
3757
|
tag: tags.emphasis,
|
|
3759
|
-
class: italic
|
|
3758
|
+
class: "italic"
|
|
3760
3759
|
},
|
|
3761
3760
|
{
|
|
3762
3761
|
tag: tags.strong,
|
|
3763
|
-
class: bold
|
|
3762
|
+
class: "font-bold"
|
|
3764
3763
|
},
|
|
3765
3764
|
{
|
|
3766
3765
|
tag: tags.strikethrough,
|
|
3767
|
-
class:
|
|
3766
|
+
class: "line-through"
|
|
3768
3767
|
},
|
|
3769
3768
|
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
3770
3769
|
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
@@ -3776,13 +3775,13 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
3776
3775
|
markdownTags.CodeText,
|
|
3777
3776
|
markdownTags.InlineCode
|
|
3778
3777
|
],
|
|
3779
|
-
class: code
|
|
3778
|
+
class: theme.code
|
|
3780
3779
|
},
|
|
3781
3780
|
{
|
|
3782
3781
|
tag: [
|
|
3783
3782
|
markdownTags.QuoteMark
|
|
3784
3783
|
],
|
|
3785
|
-
class: blockquote
|
|
3784
|
+
class: theme.blockquote
|
|
3786
3785
|
},
|
|
3787
3786
|
{
|
|
3788
3787
|
tag: [
|
|
@@ -3793,108 +3792,11 @@ var markdownHighlightStyle = (readonly) => {
|
|
|
3793
3792
|
], {
|
|
3794
3793
|
scope: markdownLanguage2,
|
|
3795
3794
|
all: {
|
|
3796
|
-
fontFamily: getToken("fontFamily.body"
|
|
3795
|
+
fontFamily: getToken("fontFamily.body")
|
|
3797
3796
|
}
|
|
3798
3797
|
});
|
|
3799
3798
|
};
|
|
3800
3799
|
|
|
3801
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/link-paste.ts
|
|
3802
|
-
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3803
|
-
import { Transaction } from "@codemirror/state";
|
|
3804
|
-
import { ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
3805
|
-
var linkPastePlugin = ViewPlugin5.fromClass(class {
|
|
3806
|
-
update(update2) {
|
|
3807
|
-
for (const tr of update2.transactions) {
|
|
3808
|
-
const event = tr.annotation(Transaction.userEvent);
|
|
3809
|
-
if (event === "input.paste") {
|
|
3810
|
-
const changes = tr.changes;
|
|
3811
|
-
if (changes.empty) {
|
|
3812
|
-
return;
|
|
3813
|
-
}
|
|
3814
|
-
changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
3815
|
-
const insertedUrl = getValidUrl(update2.view.state.sliceDoc(fromB, toB));
|
|
3816
|
-
if (insertedUrl && isValidPosition(update2.view.state, fromB)) {
|
|
3817
|
-
const replacedText = tr.startState.sliceDoc(fromA, toA);
|
|
3818
|
-
setTimeout(() => {
|
|
3819
|
-
update2.view.dispatch(update2.view.state.update({
|
|
3820
|
-
changes: {
|
|
3821
|
-
from: fromA,
|
|
3822
|
-
to: toB,
|
|
3823
|
-
insert: createLink(insertedUrl, replacedText)
|
|
3824
|
-
}
|
|
3825
|
-
}));
|
|
3826
|
-
});
|
|
3827
|
-
}
|
|
3828
|
-
});
|
|
3829
|
-
}
|
|
3830
|
-
}
|
|
3831
|
-
}
|
|
3832
|
-
});
|
|
3833
|
-
var createLink = (url, label) => {
|
|
3834
|
-
const { host, pathname } = url;
|
|
3835
|
-
const [, extension] = pathname.split(".");
|
|
3836
|
-
const imageExtensions = [
|
|
3837
|
-
"jpg",
|
|
3838
|
-
"jpeg",
|
|
3839
|
-
"png",
|
|
3840
|
-
"gif",
|
|
3841
|
-
"svg",
|
|
3842
|
-
"webp"
|
|
3843
|
-
];
|
|
3844
|
-
if (imageExtensions.includes(extension)) {
|
|
3845
|
-
return ``;
|
|
3846
|
-
}
|
|
3847
|
-
if (!label) {
|
|
3848
|
-
label = createLinkLabel(url);
|
|
3849
|
-
}
|
|
3850
|
-
return `[${label}](${url})`;
|
|
3851
|
-
};
|
|
3852
|
-
var createLinkLabel = (url) => {
|
|
3853
|
-
let { protocol, host, pathname } = url;
|
|
3854
|
-
if (protocol === "http:" || protocol === "https:") {
|
|
3855
|
-
protocol = "";
|
|
3856
|
-
}
|
|
3857
|
-
host = host.replace(/^www\./, "");
|
|
3858
|
-
return [
|
|
3859
|
-
protocol,
|
|
3860
|
-
host
|
|
3861
|
-
].filter(Boolean).join("//") + (pathname !== "/" ? pathname : "");
|
|
3862
|
-
};
|
|
3863
|
-
var getValidUrl = (str) => {
|
|
3864
|
-
const validProtocols = [
|
|
3865
|
-
"http:",
|
|
3866
|
-
"https:",
|
|
3867
|
-
"mailto:",
|
|
3868
|
-
"tel:"
|
|
3869
|
-
];
|
|
3870
|
-
try {
|
|
3871
|
-
const url = new URL(str);
|
|
3872
|
-
if (!validProtocols.includes(url.protocol)) {
|
|
3873
|
-
return void 0;
|
|
3874
|
-
}
|
|
3875
|
-
return url;
|
|
3876
|
-
} catch (_err) {
|
|
3877
|
-
return void 0;
|
|
3878
|
-
}
|
|
3879
|
-
};
|
|
3880
|
-
var isValidPosition = (state2, pos) => {
|
|
3881
|
-
const invalidPositions = /* @__PURE__ */ new Set([
|
|
3882
|
-
"Link",
|
|
3883
|
-
"LinkMark",
|
|
3884
|
-
"Code",
|
|
3885
|
-
"FencedCode"
|
|
3886
|
-
]);
|
|
3887
|
-
const tree = syntaxTree3(state2);
|
|
3888
|
-
let node = tree.resolveInner(pos, -1);
|
|
3889
|
-
while (node) {
|
|
3890
|
-
if (invalidPositions.has(node.name)) {
|
|
3891
|
-
return false;
|
|
3892
|
-
}
|
|
3893
|
-
node = node.parent;
|
|
3894
|
-
}
|
|
3895
|
-
return true;
|
|
3896
|
-
};
|
|
3897
|
-
|
|
3898
3800
|
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
3899
3801
|
var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
3900
3802
|
return [
|
|
@@ -3920,8 +3822,8 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
|
3920
3822
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
3921
3823
|
// Custom styles.
|
|
3922
3824
|
syntaxHighlighting(markdownHighlightStyle()),
|
|
3923
|
-
linkPastePlugin,
|
|
3924
3825
|
keymap7.of([
|
|
3826
|
+
// TODO(burdon): Indent by 4 if in task list.
|
|
3925
3827
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
3926
3828
|
indentWithTab2,
|
|
3927
3829
|
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
@@ -3940,7 +3842,7 @@ import { invariant as invariant4 } from "@dxos/invariant";
|
|
|
3940
3842
|
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
3941
3843
|
|
|
3942
3844
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3943
|
-
import { syntaxTree as
|
|
3845
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3944
3846
|
import { StateField as StateField6 } from "@codemirror/state";
|
|
3945
3847
|
import { Decoration as Decoration5, EditorView as EditorView12, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
3946
3848
|
var image = (_options = {}) => {
|
|
@@ -3983,7 +3885,7 @@ var preloadImage = (url) => {
|
|
|
3983
3885
|
var buildDecorations = (from, to, state2) => {
|
|
3984
3886
|
const decorations = [];
|
|
3985
3887
|
const cursor = state2.selection.main.head;
|
|
3986
|
-
|
|
3888
|
+
syntaxTree3(state2).iterate({
|
|
3987
3889
|
enter: (node) => {
|
|
3988
3890
|
if (node.name === "Image") {
|
|
3989
3891
|
const urlNode = node.node.getChild("URL");
|
|
@@ -4022,6 +3924,103 @@ var ImageWidget = class extends WidgetType3 {
|
|
|
4022
3924
|
var imageUpload = (options = {}) => {
|
|
4023
3925
|
};
|
|
4024
3926
|
|
|
3927
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/link-paste.ts
|
|
3928
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
3929
|
+
import { Transaction } from "@codemirror/state";
|
|
3930
|
+
import { ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
3931
|
+
var linkPastePlugin = ViewPlugin5.fromClass(class {
|
|
3932
|
+
update(update2) {
|
|
3933
|
+
for (const tr of update2.transactions) {
|
|
3934
|
+
const event = tr.annotation(Transaction.userEvent);
|
|
3935
|
+
if (event === "input.paste") {
|
|
3936
|
+
const changes = tr.changes;
|
|
3937
|
+
if (changes.empty) {
|
|
3938
|
+
return;
|
|
3939
|
+
}
|
|
3940
|
+
changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
3941
|
+
const insertedUrl = getValidUrl(update2.view.state.sliceDoc(fromB, toB));
|
|
3942
|
+
if (insertedUrl && isValidPosition(update2.view.state, fromB)) {
|
|
3943
|
+
const replacedText = tr.startState.sliceDoc(fromA, toA);
|
|
3944
|
+
setTimeout(() => {
|
|
3945
|
+
update2.view.dispatch(update2.view.state.update({
|
|
3946
|
+
changes: {
|
|
3947
|
+
from: fromA,
|
|
3948
|
+
to: toB,
|
|
3949
|
+
insert: createLink(insertedUrl, replacedText)
|
|
3950
|
+
}
|
|
3951
|
+
}));
|
|
3952
|
+
});
|
|
3953
|
+
}
|
|
3954
|
+
});
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
});
|
|
3959
|
+
var createLink = (url, label) => {
|
|
3960
|
+
const { host, pathname } = url;
|
|
3961
|
+
const [, extension] = pathname.split(".");
|
|
3962
|
+
const imageExtensions = [
|
|
3963
|
+
"jpg",
|
|
3964
|
+
"jpeg",
|
|
3965
|
+
"png",
|
|
3966
|
+
"gif",
|
|
3967
|
+
"svg",
|
|
3968
|
+
"webp"
|
|
3969
|
+
];
|
|
3970
|
+
if (imageExtensions.includes(extension)) {
|
|
3971
|
+
return ``;
|
|
3972
|
+
}
|
|
3973
|
+
if (!label) {
|
|
3974
|
+
label = createLinkLabel(url);
|
|
3975
|
+
}
|
|
3976
|
+
return `[${label}](${url})`;
|
|
3977
|
+
};
|
|
3978
|
+
var createLinkLabel = (url) => {
|
|
3979
|
+
let { protocol, host, pathname } = url;
|
|
3980
|
+
if (protocol === "http:" || protocol === "https:") {
|
|
3981
|
+
protocol = "";
|
|
3982
|
+
}
|
|
3983
|
+
host = host.replace(/^www\./, "");
|
|
3984
|
+
return [
|
|
3985
|
+
protocol,
|
|
3986
|
+
host
|
|
3987
|
+
].filter(Boolean).join("//") + (pathname !== "/" ? pathname : "");
|
|
3988
|
+
};
|
|
3989
|
+
var getValidUrl = (str) => {
|
|
3990
|
+
const validProtocols = [
|
|
3991
|
+
"http:",
|
|
3992
|
+
"https:",
|
|
3993
|
+
"mailto:",
|
|
3994
|
+
"tel:"
|
|
3995
|
+
];
|
|
3996
|
+
try {
|
|
3997
|
+
const url = new URL(str);
|
|
3998
|
+
if (!validProtocols.includes(url.protocol)) {
|
|
3999
|
+
return void 0;
|
|
4000
|
+
}
|
|
4001
|
+
return url;
|
|
4002
|
+
} catch (_err) {
|
|
4003
|
+
return void 0;
|
|
4004
|
+
}
|
|
4005
|
+
};
|
|
4006
|
+
var isValidPosition = (state2, pos) => {
|
|
4007
|
+
const invalidPositions = /* @__PURE__ */ new Set([
|
|
4008
|
+
"Link",
|
|
4009
|
+
"LinkMark",
|
|
4010
|
+
"Code",
|
|
4011
|
+
"FencedCode"
|
|
4012
|
+
]);
|
|
4013
|
+
const tree = syntaxTree4(state2);
|
|
4014
|
+
let node = tree.resolveInner(pos, -1);
|
|
4015
|
+
while (node) {
|
|
4016
|
+
if (invalidPositions.has(node.name)) {
|
|
4017
|
+
return false;
|
|
4018
|
+
}
|
|
4019
|
+
node = node.parent;
|
|
4020
|
+
}
|
|
4021
|
+
return true;
|
|
4022
|
+
};
|
|
4023
|
+
|
|
4025
4024
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
4026
4025
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4027
4026
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField7 } from "@codemirror/state";
|
|
@@ -4155,8 +4154,9 @@ var CheckboxWidget = class extends WidgetType5 {
|
|
|
4155
4154
|
}
|
|
4156
4155
|
toDOM(view) {
|
|
4157
4156
|
const input = document.createElement("input");
|
|
4158
|
-
input.className = "cm-task-checkbox ch-checkbox
|
|
4157
|
+
input.className = "cm-task-checkbox ch-checkbox";
|
|
4159
4158
|
input.type = "checkbox";
|
|
4159
|
+
input.tabIndex = -1;
|
|
4160
4160
|
input.checked = this._checked;
|
|
4161
4161
|
if (view.state.readOnly) {
|
|
4162
4162
|
input.setAttribute("disabled", "true");
|
|
@@ -4244,7 +4244,7 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4244
4244
|
const getHeaderLevels = (node, level) => {
|
|
4245
4245
|
invariant4(level > 0, void 0, {
|
|
4246
4246
|
F: __dxlog_file10,
|
|
4247
|
-
L:
|
|
4247
|
+
L: 159,
|
|
4248
4248
|
S: void 0,
|
|
4249
4249
|
A: [
|
|
4250
4250
|
"level > 0",
|
|
@@ -4283,7 +4283,7 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4283
4283
|
const getCurrentList = () => {
|
|
4284
4284
|
invariant4(listLevels.length, void 0, {
|
|
4285
4285
|
F: __dxlog_file10,
|
|
4286
|
-
L:
|
|
4286
|
+
L: 181,
|
|
4287
4287
|
S: void 0,
|
|
4288
4288
|
A: [
|
|
4289
4289
|
"listLevels.length",
|
|
@@ -4306,20 +4306,23 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4306
4306
|
headers[level - 1].number++;
|
|
4307
4307
|
}
|
|
4308
4308
|
const editing = editingRange(state2, node, focus);
|
|
4309
|
-
if (
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4309
|
+
if (editing) {
|
|
4310
|
+
break;
|
|
4311
|
+
}
|
|
4312
|
+
const mark = node.node.firstChild;
|
|
4313
|
+
if (mark?.name === "HeaderMark") {
|
|
4314
|
+
const { from, to = 6 } = options.numberedHeadings ?? {};
|
|
4315
|
+
const text = view.state.sliceDoc(node.from, node.to);
|
|
4316
|
+
const len = text.match(/[#\s]+/)[0].length;
|
|
4317
|
+
if (!from || level < from || level > to) {
|
|
4318
|
+
atomicDeco.add(mark.from, mark.from + len, hide);
|
|
4319
|
+
} else {
|
|
4320
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
|
4321
|
+
if (num.length) {
|
|
4322
|
+
atomicDeco.add(mark.from, mark.from + len, Decoration7.replace({
|
|
4323
|
+
widget: new TextWidget(num, theme.heading(level))
|
|
4324
|
+
}));
|
|
4319
4325
|
}
|
|
4320
|
-
deco.add(node.from, node.to, Decoration7.replace({
|
|
4321
|
-
widget: new TextWidget(text, heading(level))
|
|
4322
|
-
}));
|
|
4323
4326
|
}
|
|
4324
4327
|
}
|
|
4325
4328
|
return false;
|
|
@@ -4519,13 +4522,14 @@ var decorateMarkdown = (options = {}) => {
|
|
|
4519
4522
|
]
|
|
4520
4523
|
}),
|
|
4521
4524
|
formattingStyles,
|
|
4525
|
+
linkPastePlugin,
|
|
4522
4526
|
image(),
|
|
4523
4527
|
table()
|
|
4524
4528
|
];
|
|
4525
4529
|
};
|
|
4526
4530
|
var formattingStyles = EditorView14.baseTheme({
|
|
4527
4531
|
"& .cm-code": {
|
|
4528
|
-
fontFamily: getToken("fontFamily.mono"
|
|
4532
|
+
fontFamily: getToken("fontFamily.mono")
|
|
4529
4533
|
},
|
|
4530
4534
|
"& .cm-codeblock-line": {
|
|
4531
4535
|
paddingInline: "1rem !important"
|
|
@@ -4578,7 +4582,6 @@ var formattingStyles = EditorView14.baseTheme({
|
|
|
4578
4582
|
"& .cm-list-mark": {
|
|
4579
4583
|
display: "inline-block",
|
|
4580
4584
|
textAlign: "right",
|
|
4581
|
-
color: getToken("extend.colors.neutral.500"),
|
|
4582
4585
|
fontVariant: "tabular-nums"
|
|
4583
4586
|
},
|
|
4584
4587
|
"& .cm-list-mark-bullet": {
|
|
@@ -4717,57 +4720,69 @@ import { debounce as debounce2 } from "@dxos/async";
|
|
|
4717
4720
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
4718
4721
|
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
4719
4722
|
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/state.ts";
|
|
4720
|
-
var
|
|
4723
|
+
var stateRestoreAnnotation = "dxos.org/cm/state-restore";
|
|
4721
4724
|
var keyPrefix = "dxos.org/react-ui-editor/state";
|
|
4722
4725
|
var localStorageStateStoreAdapter = {
|
|
4723
|
-
|
|
4726
|
+
getState: (id) => {
|
|
4724
4727
|
invariant5(id, void 0, {
|
|
4725
4728
|
F: __dxlog_file12,
|
|
4726
|
-
L:
|
|
4729
|
+
L: 34,
|
|
4727
4730
|
S: void 0,
|
|
4728
4731
|
A: [
|
|
4729
4732
|
"id",
|
|
4730
4733
|
""
|
|
4731
4734
|
]
|
|
4732
4735
|
});
|
|
4733
|
-
localStorage.
|
|
4736
|
+
const state2 = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
4737
|
+
return state2 ? JSON.parse(state2) : void 0;
|
|
4734
4738
|
},
|
|
4735
|
-
|
|
4739
|
+
setState: (id, state2) => {
|
|
4736
4740
|
invariant5(id, void 0, {
|
|
4737
4741
|
F: __dxlog_file12,
|
|
4738
|
-
L:
|
|
4742
|
+
L: 40,
|
|
4739
4743
|
S: void 0,
|
|
4740
4744
|
A: [
|
|
4741
4745
|
"id",
|
|
4742
4746
|
""
|
|
4743
4747
|
]
|
|
4744
4748
|
});
|
|
4745
|
-
|
|
4746
|
-
return state2 ? JSON.parse(state2) : void 0;
|
|
4749
|
+
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state2));
|
|
4747
4750
|
}
|
|
4748
4751
|
};
|
|
4752
|
+
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
4753
|
+
return {
|
|
4754
|
+
selection,
|
|
4755
|
+
scrollIntoView: !scrollTo,
|
|
4756
|
+
effects: scrollTo ? EditorView15.scrollIntoView(scrollTo, {
|
|
4757
|
+
yMargin: 96
|
|
4758
|
+
}) : void 0,
|
|
4759
|
+
annotations: Transaction2.userEvent.of(stateRestoreAnnotation)
|
|
4760
|
+
};
|
|
4761
|
+
};
|
|
4749
4762
|
var state = ({ getState, setState } = {}) => {
|
|
4750
4763
|
const setStateDebounced = debounce2(setState, 1e3);
|
|
4751
4764
|
return [
|
|
4752
4765
|
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
4753
|
-
|
|
4766
|
+
// EditorView.domEventHandlers({
|
|
4767
|
+
// scroll: (event) => {
|
|
4768
|
+
// setStateDebounced(id, {});
|
|
4769
|
+
// },
|
|
4770
|
+
// }),
|
|
4771
|
+
EditorView15.updateListener.of(({ view, transactions }) => {
|
|
4754
4772
|
const id = view.state.facet(documentId2);
|
|
4755
|
-
if (!id || transactions.some((tr) => tr.isUserEvent(
|
|
4773
|
+
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
|
4756
4774
|
return;
|
|
4757
4775
|
}
|
|
4758
4776
|
if (setState) {
|
|
4759
|
-
const {
|
|
4777
|
+
const { scrollTop } = view.scrollDOM;
|
|
4760
4778
|
const pos = view.posAtCoords({
|
|
4761
4779
|
x: 0,
|
|
4762
|
-
y:
|
|
4780
|
+
y: scrollTop
|
|
4763
4781
|
});
|
|
4764
4782
|
if (pos !== null) {
|
|
4765
4783
|
const { anchor, head } = view.state.selection.main;
|
|
4766
4784
|
setStateDebounced(id, {
|
|
4767
|
-
scrollTo:
|
|
4768
|
-
from: pos,
|
|
4769
|
-
yMargin: 0
|
|
4770
|
-
},
|
|
4785
|
+
scrollTo: pos,
|
|
4771
4786
|
selection: {
|
|
4772
4787
|
anchor,
|
|
4773
4788
|
head
|
|
@@ -4782,13 +4797,7 @@ var state = ({ getState, setState } = {}) => {
|
|
|
4782
4797
|
run: (view) => {
|
|
4783
4798
|
const state2 = getState(view.state.facet(documentId2));
|
|
4784
4799
|
if (state2) {
|
|
4785
|
-
view.dispatch(
|
|
4786
|
-
effects: EditorView15.scrollIntoView(state2.scrollTo.from, {
|
|
4787
|
-
yMargin: 0
|
|
4788
|
-
}),
|
|
4789
|
-
selection: state2.selection,
|
|
4790
|
-
annotations: Transaction2.userEvent.of(scrollAnnotation)
|
|
4791
|
-
});
|
|
4800
|
+
view.dispatch(createEditorStateTransaction(state2));
|
|
4792
4801
|
}
|
|
4793
4802
|
return true;
|
|
4794
4803
|
}
|
|
@@ -5234,18 +5243,24 @@ var Toolbar = {
|
|
|
5234
5243
|
|
|
5235
5244
|
// packages/ui/react-ui-editor/src/defaults.ts
|
|
5236
5245
|
import { EditorView as EditorView16 } from "@codemirror/view";
|
|
5237
|
-
var editorContent = "!mt-[16px] !mli-auto w-full max-w-[min(50rem,100%-
|
|
5246
|
+
var editorContent = "!mt-[16px] !mb-[32px] !mli-auto w-full max-w-[min(50rem,100%-8rem)]";
|
|
5238
5247
|
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
5239
5248
|
var editorGutter = EditorView16.baseTheme({
|
|
5240
5249
|
".cm-gutters": {
|
|
5241
5250
|
// Match margin from content.
|
|
5242
5251
|
marginTop: "16px",
|
|
5252
|
+
marginBottom: "16px",
|
|
5243
5253
|
// Inside within content margin.
|
|
5244
5254
|
marginRight: "-32px",
|
|
5245
5255
|
width: "32px",
|
|
5246
5256
|
backgroundColor: "transparent !important"
|
|
5247
5257
|
}
|
|
5248
5258
|
});
|
|
5259
|
+
var editorMonospace = EditorView16.baseTheme({
|
|
5260
|
+
".cm-content": {
|
|
5261
|
+
fontFamily: `${getToken("fontFamily.mono")} !important`
|
|
5262
|
+
}
|
|
5263
|
+
});
|
|
5249
5264
|
|
|
5250
5265
|
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
5251
5266
|
var useActionHandler = (view) => {
|
|
@@ -5258,18 +5273,14 @@ import { EditorView as EditorView17 } from "@codemirror/view";
|
|
|
5258
5273
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
5259
5274
|
import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
|
|
5260
5275
|
import { log as log8 } from "@dxos/log";
|
|
5261
|
-
import { useDefaultValue } from "@dxos/react-ui";
|
|
5262
5276
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
5263
5277
|
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
5264
5278
|
var instanceCount = 0;
|
|
5265
5279
|
var useTextEditor = (props = {}, deps = []) => {
|
|
5266
|
-
const { id, initialValue,
|
|
5280
|
+
const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => {
|
|
5267
5281
|
return typeof props === "function" ? props() : props;
|
|
5268
5282
|
}, deps ?? []);
|
|
5269
5283
|
const [instanceId] = useState4(() => `text-editor-${++instanceCount}`);
|
|
5270
|
-
const scrollTo = useDefaultValue(_scrollTo, EditorView17.scrollIntoView(0, {
|
|
5271
|
-
yMargin: 0
|
|
5272
|
-
}));
|
|
5273
5284
|
const onUpdate = useRef2();
|
|
5274
5285
|
const [view, setView] = useState4();
|
|
5275
5286
|
const parentRef = useRef2(null);
|
|
@@ -5282,12 +5293,16 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
5282
5293
|
doc: initialValue?.length ?? 0
|
|
5283
5294
|
}, {
|
|
5284
5295
|
F: __dxlog_file13,
|
|
5285
|
-
L:
|
|
5296
|
+
L: 78,
|
|
5286
5297
|
S: void 0,
|
|
5287
5298
|
C: (f, a) => f(...a)
|
|
5288
5299
|
});
|
|
5289
|
-
let initialSelection
|
|
5290
|
-
if (
|
|
5300
|
+
let initialSelection;
|
|
5301
|
+
if (selection?.anchor && initialValue?.length) {
|
|
5302
|
+
if (selection.anchor <= initialValue.length && (selection?.head ?? 0) <= initialValue.length) {
|
|
5303
|
+
initialSelection = selection;
|
|
5304
|
+
}
|
|
5305
|
+
} else if (moveToEndOfLine && selection === void 0) {
|
|
5291
5306
|
const index = initialValue?.indexOf("\n");
|
|
5292
5307
|
const anchor = !index || index === -1 ? 0 : index;
|
|
5293
5308
|
initialSelection = {
|
|
@@ -5303,20 +5318,21 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
5303
5318
|
EditorView17.exceptionSink.of((err) => {
|
|
5304
5319
|
log8.catch(err, void 0, {
|
|
5305
5320
|
F: __dxlog_file13,
|
|
5306
|
-
L:
|
|
5321
|
+
L: 100,
|
|
5307
5322
|
S: void 0,
|
|
5308
5323
|
C: (f, a) => f(...a)
|
|
5309
5324
|
});
|
|
5310
5325
|
}),
|
|
5311
5326
|
extensions,
|
|
5312
5327
|
EditorView17.updateListener.of(() => {
|
|
5313
|
-
|
|
5328
|
+
setTimeout(() => {
|
|
5329
|
+
onUpdate.current?.();
|
|
5330
|
+
});
|
|
5314
5331
|
})
|
|
5315
5332
|
].filter(isNotFalsy4)
|
|
5316
5333
|
});
|
|
5317
5334
|
view2 = new EditorView17({
|
|
5318
5335
|
parent: parentRef.current,
|
|
5319
|
-
scrollTo,
|
|
5320
5336
|
selection: initialSelection,
|
|
5321
5337
|
state: state2,
|
|
5322
5338
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
@@ -5343,7 +5359,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
5343
5359
|
id
|
|
5344
5360
|
}, {
|
|
5345
5361
|
F: __dxlog_file13,
|
|
5346
|
-
L:
|
|
5362
|
+
L: 136,
|
|
5347
5363
|
S: void 0,
|
|
5348
5364
|
C: (f, a) => f(...a)
|
|
5349
5365
|
});
|
|
@@ -5352,17 +5368,13 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
5352
5368
|
}, deps);
|
|
5353
5369
|
useEffect3(() => {
|
|
5354
5370
|
if (view) {
|
|
5355
|
-
|
|
5356
|
-
onUpdate.current =
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
scrollIntoView: !scrollTo
|
|
5363
|
-
});
|
|
5364
|
-
};
|
|
5365
|
-
}
|
|
5371
|
+
onUpdate.current = () => {
|
|
5372
|
+
onUpdate.current = void 0;
|
|
5373
|
+
view.dispatch(createEditorStateTransaction({
|
|
5374
|
+
scrollTo,
|
|
5375
|
+
selection
|
|
5376
|
+
}));
|
|
5377
|
+
};
|
|
5366
5378
|
if (view.state.facet(editorInputMode).noTabster) {
|
|
5367
5379
|
parentRef.current?.removeAttribute("data-tabster");
|
|
5368
5380
|
}
|
|
@@ -5436,6 +5448,7 @@ export {
|
|
|
5436
5448
|
createBasicExtensions,
|
|
5437
5449
|
createComment,
|
|
5438
5450
|
createDataExtensions,
|
|
5451
|
+
createEditorStateTransaction,
|
|
5439
5452
|
createExternalCommentSync,
|
|
5440
5453
|
createMarkdownExtensions,
|
|
5441
5454
|
createThemeExtensions,
|
|
@@ -5447,6 +5460,7 @@ export {
|
|
|
5447
5460
|
editorContent,
|
|
5448
5461
|
editorGutter,
|
|
5449
5462
|
editorInputMode,
|
|
5463
|
+
editorMonospace,
|
|
5450
5464
|
editorWithToolbarLayout,
|
|
5451
5465
|
focusEvent,
|
|
5452
5466
|
folding,
|