@dxos/ui-editor 0.8.4-main.4a85c3132b → 0.8.4-main.4f23b4e393
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 +1563 -775
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +26 -6
- package/dist/lib/browser/types/index.mjs.map +4 -4
- package/dist/lib/node-esm/index.mjs +1562 -773
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +27 -6
- package/dist/lib/node-esm/types/index.mjs.map +4 -4
- package/dist/types/src/defaults.d.ts +4 -10
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/auto-scroll.d.ts +14 -2
- package/dist/types/src/extensions/auto-scroll.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +5 -2
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +4 -3
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/focus.d.ts +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts +3 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.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.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -1
- package/dist/types/src/extensions/preview/preview.d.ts +2 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/replacer.d.ts.map +1 -1
- package/dist/types/src/extensions/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scroller.d.ts +12 -10
- package/dist/types/src/extensions/scroller.d.ts.map +1 -1
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +4 -1
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +28 -8
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts +2 -2
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +4 -4
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts.map +1 -1
- package/dist/types/src/util/debug.d.ts.map +1 -1
- package/dist/types/src/util/decorations.d.ts.map +1 -1
- package/dist/types/src/util/dom.d.ts.map +1 -1
- package/dist/types/src/util/facet.d.ts.map +1 -1
- package/dist/types/src/util/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +34 -37
- package/src/defaults.ts +33 -20
- package/src/extensions/auto-scroll.ts +120 -12
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +35 -9
- package/src/extensions/automerge/automerge.ts +5 -7
- package/src/extensions/comments.ts +0 -1
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +26 -8
- package/src/extensions/folding.ts +3 -20
- package/src/extensions/index.ts +2 -1
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +11 -9
- package/src/extensions/markdown/highlight.ts +4 -10
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +37 -4
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +1 -2
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +54 -7
- package/src/extensions/scroll-past-end.ts +32 -0
- package/src/extensions/scroller.ts +49 -25
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +179 -31
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/theme.ts +45 -31
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +0 -1
- package/dist/lib/browser/chunk-HL3YF6WC.mjs +0 -22
- package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs +0 -24
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +0 -7
- package/dist/types/src/extensions/tags/streamer.d.ts +0 -12
- package/dist/types/src/extensions/tags/streamer.d.ts.map +0 -1
- package/dist/types/src/extensions/typewriter.d.ts +0 -10
- package/dist/types/src/extensions/typewriter.d.ts.map +0 -1
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
|
@@ -1,29 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EditorInputMode,
|
|
3
|
-
EditorInputModes,
|
|
4
|
-
EditorViewMode,
|
|
5
|
-
EditorViewModes
|
|
6
|
-
} from "./chunk-HL3YF6WC.mjs";
|
|
7
|
-
|
|
8
1
|
// src/index.ts
|
|
9
|
-
import { EditorState as
|
|
10
|
-
import { EditorView as
|
|
2
|
+
import { EditorState as EditorState4 } from "@codemirror/state";
|
|
3
|
+
import { EditorView as EditorView33, keymap as keymap15 } from "@codemirror/view";
|
|
11
4
|
import { tags as tags2 } from "@lezer/highlight";
|
|
12
5
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
13
6
|
|
|
14
7
|
// src/defaults.ts
|
|
15
8
|
import { mx } from "@dxos/ui-theme";
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
var editorClassNames = (role) => mx("dx-attention-surface p-0.5 data-[toolbar=disabled]:pt-2 dx-focus-ring-inset", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
10
|
+
var documentSlots = {
|
|
11
|
+
content: {
|
|
12
|
+
/**
|
|
13
|
+
* CodeMirror content width.
|
|
14
|
+
* 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
|
|
15
|
+
* 50rem = 800px. Maximum content width for solo mode.
|
|
16
|
+
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
|
17
|
+
*/
|
|
18
|
+
className: mx(
|
|
19
|
+
// Inline-size container for widget sizing (children use `max-w-[100cqi]`).
|
|
20
|
+
// NOTE: Use inline-size, not full size containment — `container-type: size` on the
|
|
21
|
+
// editor content breaks CodeMirror's viewport measurement, leaving blank gaps during
|
|
22
|
+
// scroll until a click forces a re-measure.
|
|
23
|
+
"dx-inline-size-container",
|
|
24
|
+
// Wider margin for web (vs. mobile).
|
|
25
|
+
"pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]",
|
|
26
|
+
"mx-auto! w-full"
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var compactSlots = {
|
|
31
|
+
content: {
|
|
32
|
+
className: "mx-2!"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var mobileSlots = {
|
|
21
36
|
content: {
|
|
22
|
-
className:
|
|
37
|
+
className: "mx-2!"
|
|
23
38
|
}
|
|
24
39
|
};
|
|
25
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
26
|
-
var stackItemContentEditorClassNames = (role) => mx("dx-attention-surface p-0.5 dx-focus-ring-inset data-[toolbar=disabled]:pt-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24" : "dx-container overflow-hidden");
|
|
27
40
|
|
|
28
41
|
// src/extensions/annotations.ts
|
|
29
42
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
@@ -207,7 +220,7 @@ var singleValueFacet = (defaultValue) => Facet.define({
|
|
|
207
220
|
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
208
221
|
var defaultCursorConverter = {
|
|
209
222
|
toCursor: (position) => position.toString(),
|
|
210
|
-
fromCursor: (
|
|
223
|
+
fromCursor: (cursor) => parseInt(cursor)
|
|
211
224
|
};
|
|
212
225
|
var Cursor = class _Cursor {
|
|
213
226
|
static converter = singleValueFacet(defaultCursorConverter);
|
|
@@ -220,9 +233,9 @@ var Cursor = class _Cursor {
|
|
|
220
233
|
to
|
|
221
234
|
].join(":");
|
|
222
235
|
};
|
|
223
|
-
static getRangeFromCursor = (state,
|
|
236
|
+
static getRangeFromCursor = (state, cursor) => {
|
|
224
237
|
const cursorConverter2 = state.facet(_Cursor.converter);
|
|
225
|
-
const parts =
|
|
238
|
+
const parts = cursor.split(":");
|
|
226
239
|
const from = cursorConverter2.fromCursor(parts[0]);
|
|
227
240
|
const to = cursorConverter2.fromCursor(parts[1]);
|
|
228
241
|
return from !== void 0 && to !== void 0 ? {
|
|
@@ -258,12 +271,7 @@ var wrapWithCatch = (fn, label) => {
|
|
|
258
271
|
} catch (err) {
|
|
259
272
|
log.catch(err, {
|
|
260
273
|
label
|
|
261
|
-
}, {
|
|
262
|
-
F: __dxlog_file,
|
|
263
|
-
L: 20,
|
|
264
|
-
S: void 0,
|
|
265
|
-
C: (f, a) => f(...a)
|
|
266
|
-
});
|
|
274
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 13, S: void 0 });
|
|
267
275
|
}
|
|
268
276
|
};
|
|
269
277
|
};
|
|
@@ -289,12 +297,7 @@ var logChanges = (trs) => {
|
|
|
289
297
|
if (changes.length) {
|
|
290
298
|
log("changes", {
|
|
291
299
|
changes
|
|
292
|
-
}, {
|
|
293
|
-
F: __dxlog_file,
|
|
294
|
-
L: 54,
|
|
295
|
-
S: void 0,
|
|
296
|
-
C: (f, a) => f(...a)
|
|
297
|
-
});
|
|
300
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 44, S: void 0 });
|
|
298
301
|
}
|
|
299
302
|
};
|
|
300
303
|
|
|
@@ -360,30 +363,37 @@ var insertAtLineStart = (view, from, insert) => {
|
|
|
360
363
|
};
|
|
361
364
|
|
|
362
365
|
// src/extensions/autocomplete/placeholder.ts
|
|
363
|
-
var placeholder = ({ content, delay = 3e3 }) => {
|
|
366
|
+
var placeholder = ({ content, delay = 3e3, focusOnly = false }) => {
|
|
364
367
|
const plugin = ViewPlugin3.fromClass(class {
|
|
365
368
|
_timeout;
|
|
366
369
|
_decorations = Decoration3.none;
|
|
367
370
|
update(update2) {
|
|
371
|
+
if (!update2.docChanged && !update2.selectionSet && !update2.focusChanged) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
368
374
|
if (this._timeout) {
|
|
369
375
|
window.clearTimeout(this._timeout);
|
|
370
376
|
this._timeout = void 0;
|
|
371
377
|
}
|
|
378
|
+
this._decorations = Decoration3.none;
|
|
379
|
+
if (focusOnly && !update2.view.hasFocus) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
372
382
|
const activeLine = update2.view.state.doc.lineAt(update2.view.state.selection.main.head);
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const lineStart = activeLine.from;
|
|
376
|
-
this._timeout = setTimeout(() => {
|
|
377
|
-
this._decorations = Decoration3.set([
|
|
378
|
-
Decoration3.widget({
|
|
379
|
-
widget: new PlaceholderWidget(content),
|
|
380
|
-
side: 1
|
|
381
|
-
}).range(lineStart)
|
|
382
|
-
]);
|
|
383
|
-
update2.view.update([]);
|
|
384
|
-
}, delay);
|
|
383
|
+
if (activeLine.text.trim() !== "") {
|
|
384
|
+
return;
|
|
385
385
|
}
|
|
386
|
-
|
|
386
|
+
const lineStart = activeLine.from;
|
|
387
|
+
const view = update2.view;
|
|
388
|
+
this._timeout = setTimeout(() => {
|
|
389
|
+
this._decorations = Decoration3.set([
|
|
390
|
+
Decoration3.widget({
|
|
391
|
+
widget: new PlaceholderWidget(content),
|
|
392
|
+
side: 1
|
|
393
|
+
}).range(lineStart)
|
|
394
|
+
]);
|
|
395
|
+
view.update([]);
|
|
396
|
+
}, delay);
|
|
387
397
|
}
|
|
388
398
|
destroy() {
|
|
389
399
|
if (this._timeout) {
|
|
@@ -502,9 +512,11 @@ var typeahead = ({ onComplete } = {}) => {
|
|
|
502
512
|
};
|
|
503
513
|
|
|
504
514
|
// src/extensions/auto-scroll.ts
|
|
515
|
+
import { StateEffect as StateEffect2 } from "@codemirror/state";
|
|
505
516
|
import { EditorView as EditorView5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
506
517
|
import { addEventListener, combine, throttle } from "@dxos/async";
|
|
507
518
|
import { Domino } from "@dxos/ui";
|
|
519
|
+
import { getSize } from "@dxos/ui-theme";
|
|
508
520
|
|
|
509
521
|
// src/extensions/scroller.ts
|
|
510
522
|
import { StateEffect } from "@codemirror/state";
|
|
@@ -561,15 +573,14 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
561
573
|
}
|
|
562
574
|
requestAnimationFrame(() => {
|
|
563
575
|
this.view.scrollDOM.scrollTo({
|
|
564
|
-
top: targetScrollTop
|
|
565
|
-
behavior
|
|
576
|
+
top: targetScrollTop
|
|
566
577
|
});
|
|
567
578
|
});
|
|
568
579
|
}
|
|
569
580
|
});
|
|
570
581
|
return [
|
|
571
582
|
scrollPlugin,
|
|
572
|
-
// Listen for effect.
|
|
583
|
+
// Listen for effect.
|
|
573
584
|
EditorView4.updateListener.of((update2) => {
|
|
574
585
|
update2.transactions.forEach((transaction) => {
|
|
575
586
|
try {
|
|
@@ -584,23 +595,19 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
584
595
|
}
|
|
585
596
|
}
|
|
586
597
|
} catch (err) {
|
|
587
|
-
log2.catch(err, void 0, {
|
|
588
|
-
F: __dxlog_file2,
|
|
589
|
-
L: 145,
|
|
590
|
-
S: void 0,
|
|
591
|
-
C: (f, a) => f(...a)
|
|
592
|
-
});
|
|
598
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 91, S: void 0 });
|
|
593
599
|
}
|
|
594
600
|
});
|
|
595
601
|
}),
|
|
596
602
|
// Styles.
|
|
597
603
|
EditorView4.theme({
|
|
598
|
-
".cm-content": {
|
|
599
|
-
paddingBottom: `${overScroll}px`
|
|
600
|
-
},
|
|
601
604
|
".cm-scroller": {
|
|
602
|
-
|
|
603
|
-
|
|
605
|
+
overflowY: "scroll",
|
|
606
|
+
// Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks
|
|
607
|
+
// expanding their TogglePanel), the browser picks a stable element near the viewport
|
|
608
|
+
// top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning
|
|
609
|
+
// logic still has the final word when pinned (forces scrollTop to scrollHeight).
|
|
610
|
+
overflowAnchor: "auto"
|
|
604
611
|
},
|
|
605
612
|
".cm-scroller.cm-hide-scrollbar::-webkit-scrollbar": {
|
|
606
613
|
display: "none"
|
|
@@ -612,6 +619,16 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
612
619
|
"&:hover .cm-scroller::-webkit-scrollbar-thumb": {
|
|
613
620
|
background: "var(--color-scrollbar-thumb)"
|
|
614
621
|
},
|
|
622
|
+
// Spacer below the last text line. Implemented as a real block pseudo-element
|
|
623
|
+
// (rather than `padding-bottom` on `.cm-content`) so it materializes in the
|
|
624
|
+
// scroller's `scrollHeight` regardless of how `padding` is reset by the base
|
|
625
|
+
// theme or downstream classes — this is what gives auto-scroll its head-room
|
|
626
|
+
// so the last line stays `overScroll` px above the viewport bottom.
|
|
627
|
+
".cm-content::after": {
|
|
628
|
+
content: '""',
|
|
629
|
+
display: "block",
|
|
630
|
+
height: `${overScroll}px`
|
|
631
|
+
},
|
|
615
632
|
".cm-scroll-button": {
|
|
616
633
|
position: "absolute",
|
|
617
634
|
bottom: "0.5rem",
|
|
@@ -620,22 +637,28 @@ var scroller = ({ overScroll = 0 } = {}) => {
|
|
|
620
637
|
})
|
|
621
638
|
];
|
|
622
639
|
};
|
|
623
|
-
function createCrawler(view,
|
|
640
|
+
function createCrawler(view, omega = 5, snapThreshold = 5, snapVelocity = 50) {
|
|
624
641
|
const el = view.scrollDOM;
|
|
625
642
|
let currentTop = 0;
|
|
643
|
+
let velocity = 0;
|
|
626
644
|
let rafId = null;
|
|
627
|
-
|
|
645
|
+
let lastTime = 0;
|
|
646
|
+
function frame(now) {
|
|
647
|
+
const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1e3);
|
|
648
|
+
lastTime = now;
|
|
628
649
|
const targetTop = el.scrollHeight - el.clientHeight;
|
|
629
650
|
const delta = targetTop - currentTop;
|
|
630
|
-
|
|
631
|
-
if (absDelta < targetDelta) {
|
|
651
|
+
if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {
|
|
632
652
|
el.scrollTop = targetTop;
|
|
633
653
|
currentTop = targetTop;
|
|
654
|
+
velocity = 0;
|
|
634
655
|
rafId = null;
|
|
656
|
+
lastTime = 0;
|
|
635
657
|
return;
|
|
636
658
|
}
|
|
637
|
-
const
|
|
638
|
-
|
|
659
|
+
const accel = omega * omega * delta - 2 * omega * velocity;
|
|
660
|
+
velocity += accel * dt;
|
|
661
|
+
currentTop += velocity * dt;
|
|
639
662
|
el.scrollTop = currentTop;
|
|
640
663
|
rafId = requestAnimationFrame(frame);
|
|
641
664
|
}
|
|
@@ -643,12 +666,15 @@ function createCrawler(view, k = 0.3, maxStep = 2, targetDelta = 0.5) {
|
|
|
643
666
|
scroll: () => {
|
|
644
667
|
if (rafId === null) {
|
|
645
668
|
currentTop = el.scrollTop;
|
|
669
|
+
lastTime = 0;
|
|
646
670
|
rafId = requestAnimationFrame(frame);
|
|
647
671
|
}
|
|
648
672
|
},
|
|
649
673
|
cancel: () => {
|
|
650
674
|
if (rafId !== null) {
|
|
651
675
|
cancelAnimationFrame(rafId);
|
|
676
|
+
velocity = 0;
|
|
677
|
+
lastTime = 0;
|
|
652
678
|
rafId = null;
|
|
653
679
|
}
|
|
654
680
|
}
|
|
@@ -656,26 +682,64 @@ function createCrawler(view, k = 0.3, maxStep = 2, targetDelta = 0.5) {
|
|
|
656
682
|
}
|
|
657
683
|
|
|
658
684
|
// src/extensions/auto-scroll.ts
|
|
659
|
-
var
|
|
685
|
+
var autoScrollEffect = StateEffect2.define();
|
|
686
|
+
var autoScroll = ({ scrollOnResize = true } = {}) => {
|
|
660
687
|
let buttonContainer;
|
|
661
688
|
let isPinned = true;
|
|
689
|
+
let jumpPending = false;
|
|
690
|
+
let enabled = true;
|
|
691
|
+
let firstUpdate = true;
|
|
662
692
|
const setPinned = (pinned) => {
|
|
663
693
|
buttonContainer?.classList.toggle("opacity-0", pinned);
|
|
664
694
|
isPinned = pinned;
|
|
665
695
|
};
|
|
666
696
|
return [
|
|
667
|
-
// Update listener for
|
|
668
|
-
EditorView5.updateListener.of((
|
|
697
|
+
// Update listener for scrolling when content changes.
|
|
698
|
+
EditorView5.updateListener.of((update2) => {
|
|
699
|
+
const { view, heightChanged, state, startState } = update2;
|
|
700
|
+
for (const tr of update2.transactions) {
|
|
701
|
+
for (const effect of tr.effects) {
|
|
702
|
+
if (effect.is(autoScrollEffect)) {
|
|
703
|
+
enabled = effect.value;
|
|
704
|
+
if (enabled) {
|
|
705
|
+
setPinned(true);
|
|
706
|
+
view.dispatch({
|
|
707
|
+
effects: scrollerCrawlEffect.of(true)
|
|
708
|
+
});
|
|
709
|
+
} else {
|
|
710
|
+
view.dispatch({
|
|
711
|
+
effects: scrollerCrawlEffect.of(false)
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (!enabled) {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {
|
|
721
|
+
firstUpdate = false;
|
|
722
|
+
jumpPending = true;
|
|
723
|
+
requestAnimationFrame(() => {
|
|
724
|
+
view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;
|
|
725
|
+
jumpPending = false;
|
|
726
|
+
});
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
firstUpdate = false;
|
|
730
|
+
if (jumpPending) {
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
669
733
|
if (heightChanged) {
|
|
670
734
|
if (isPinned) {
|
|
671
735
|
const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;
|
|
672
736
|
const delta = scrollHeight - scrollTop - clientHeight;
|
|
673
|
-
if (delta > 0
|
|
737
|
+
if (delta > 0) {
|
|
674
738
|
setPinned(true);
|
|
675
739
|
view.dispatch({
|
|
676
740
|
effects: scrollerCrawlEffect.of(true)
|
|
677
741
|
});
|
|
678
|
-
} else if (delta <
|
|
742
|
+
} else if (delta < -1) {
|
|
679
743
|
setPinned(false);
|
|
680
744
|
}
|
|
681
745
|
} else {
|
|
@@ -685,6 +749,46 @@ var autoScroll = (_ = {}) => {
|
|
|
685
749
|
}
|
|
686
750
|
}
|
|
687
751
|
}),
|
|
752
|
+
// Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,
|
|
753
|
+
// window resize). Doc-driven height changes are handled by the updateListener above; this
|
|
754
|
+
// observer covers the case where the viewport changes while the doc length is unchanged.
|
|
755
|
+
scrollOnResize ? ViewPlugin6.fromClass(class {
|
|
756
|
+
observer;
|
|
757
|
+
firstObservation = true;
|
|
758
|
+
destroyed = false;
|
|
759
|
+
constructor(view) {
|
|
760
|
+
const onResize = throttle(() => {
|
|
761
|
+
if (this.destroyed || !enabled) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
setPinned(true);
|
|
765
|
+
requestAnimationFrame(() => {
|
|
766
|
+
if (this.destroyed) {
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
view.scrollDOM.scrollTo({
|
|
770
|
+
top: view.scrollDOM.scrollHeight,
|
|
771
|
+
behavior: "instant"
|
|
772
|
+
});
|
|
773
|
+
view.dispatch({
|
|
774
|
+
effects: scrollerCrawlEffect.of(false)
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
}, 50);
|
|
778
|
+
this.observer = new ResizeObserver(() => {
|
|
779
|
+
if (this.firstObservation) {
|
|
780
|
+
this.firstObservation = false;
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
onResize();
|
|
784
|
+
});
|
|
785
|
+
this.observer.observe(view.scrollDOM);
|
|
786
|
+
}
|
|
787
|
+
destroy() {
|
|
788
|
+
this.destroyed = true;
|
|
789
|
+
this.observer.disconnect();
|
|
790
|
+
}
|
|
791
|
+
}) : [],
|
|
688
792
|
// Detect user scroll and unpin (or re-pin if scrolled to the bottom).
|
|
689
793
|
ViewPlugin6.fromClass(class {
|
|
690
794
|
cleanup;
|
|
@@ -710,12 +814,12 @@ var autoScroll = (_ = {}) => {
|
|
|
710
814
|
// Scroll button.
|
|
711
815
|
ViewPlugin6.fromClass(class {
|
|
712
816
|
constructor(view) {
|
|
713
|
-
const icon = Domino.of("dx-icon").attributes({
|
|
817
|
+
const icon = Domino.of("dx-icon").classNames(getSize(4)).attributes({
|
|
714
818
|
icon: "ph--arrow-down--regular"
|
|
715
819
|
});
|
|
716
820
|
const button = Domino.of("button").classNames("dx-button bg-accent-surface").attributes({
|
|
717
821
|
"data-density": "fine"
|
|
718
|
-
}).
|
|
822
|
+
}).append(icon).on("click", () => {
|
|
719
823
|
setPinned(true);
|
|
720
824
|
view.dispatch({
|
|
721
825
|
effects: scrollerLineEffect.of({
|
|
@@ -725,7 +829,7 @@ var autoScroll = (_ = {}) => {
|
|
|
725
829
|
})
|
|
726
830
|
});
|
|
727
831
|
});
|
|
728
|
-
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").
|
|
832
|
+
buttonContainer = Domino.of("div").classNames("cm-scroll-button transition-opacity duration-300 opacity-0").append(button).root;
|
|
729
833
|
view.scrollDOM.parentElement.appendChild(buttonContainer);
|
|
730
834
|
}
|
|
731
835
|
})
|
|
@@ -760,35 +864,25 @@ var cursorConverter = (accessor) => ({
|
|
|
760
864
|
try {
|
|
761
865
|
return toCursor(accessor, pos, assoc);
|
|
762
866
|
} catch (err) {
|
|
763
|
-
log3.catch(err, void 0, {
|
|
764
|
-
F: __dxlog_file3,
|
|
765
|
-
L: 15,
|
|
766
|
-
S: void 0,
|
|
767
|
-
C: (f, a) => f(...a)
|
|
768
|
-
});
|
|
867
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 11, S: void 0 });
|
|
769
868
|
return "";
|
|
770
869
|
}
|
|
771
870
|
},
|
|
772
|
-
fromCursor: (
|
|
871
|
+
fromCursor: (cursor) => {
|
|
773
872
|
try {
|
|
774
|
-
return fromCursor(accessor,
|
|
873
|
+
return fromCursor(accessor, cursor);
|
|
775
874
|
} catch (err) {
|
|
776
|
-
log3.catch(err, void 0, {
|
|
777
|
-
F: __dxlog_file3,
|
|
778
|
-
L: 24,
|
|
779
|
-
S: void 0,
|
|
780
|
-
C: (f, a) => f(...a)
|
|
781
|
-
});
|
|
875
|
+
log3.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 19, S: void 0 });
|
|
782
876
|
return 0;
|
|
783
877
|
}
|
|
784
878
|
}
|
|
785
879
|
});
|
|
786
880
|
|
|
787
881
|
// src/extensions/automerge/defs.ts
|
|
788
|
-
import { Annotation, StateEffect as
|
|
882
|
+
import { Annotation, StateEffect as StateEffect3 } from "@codemirror/state";
|
|
789
883
|
var getPath = (state, field) => state.field(field).path;
|
|
790
884
|
var getLastHeads = (state, field) => state.field(field).lastHeads;
|
|
791
|
-
var updateHeadsEffect =
|
|
885
|
+
var updateHeadsEffect = StateEffect3.define({});
|
|
792
886
|
var updateHeads = (newHeads) => updateHeadsEffect.of({
|
|
793
887
|
newHeads
|
|
794
888
|
});
|
|
@@ -963,12 +1057,7 @@ var Syncer = class {
|
|
|
963
1057
|
this._pending = false;
|
|
964
1058
|
}
|
|
965
1059
|
onEditorChange(view) {
|
|
966
|
-
log4("onEditorChange", void 0, {
|
|
967
|
-
F: __dxlog_file4,
|
|
968
|
-
L: 45,
|
|
969
|
-
S: this,
|
|
970
|
-
C: (f, a) => f(...a)
|
|
971
|
-
});
|
|
1060
|
+
log4("onEditorChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 35, S: this });
|
|
972
1061
|
const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
|
|
973
1062
|
const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
|
|
974
1063
|
if (newHeads) {
|
|
@@ -979,12 +1068,7 @@ var Syncer = class {
|
|
|
979
1068
|
}
|
|
980
1069
|
}
|
|
981
1070
|
onAutomergeChange(view) {
|
|
982
|
-
log4("onAutomergeChange", void 0, {
|
|
983
|
-
F: __dxlog_file4,
|
|
984
|
-
L: 60,
|
|
985
|
-
S: this,
|
|
986
|
-
C: (f, a) => f(...a)
|
|
987
|
-
});
|
|
1071
|
+
log4("onAutomergeChange", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 47, S: this });
|
|
988
1072
|
const oldHeads = getLastHeads(view.state, this._state);
|
|
989
1073
|
const newHeads = A2.getHeads(this._handle.doc());
|
|
990
1074
|
const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.doc(), oldHeads, newHeads);
|
|
@@ -1046,6 +1130,17 @@ var automerge = (accessor) => {
|
|
|
1046
1130
|
const value = DocAccessor.getValue(accessor);
|
|
1047
1131
|
const current = this._view.state.doc.toString();
|
|
1048
1132
|
if (value !== current) {
|
|
1133
|
+
this._view.dispatch({
|
|
1134
|
+
changes: {
|
|
1135
|
+
from: 0,
|
|
1136
|
+
to: this._view.state.doc.length,
|
|
1137
|
+
insert: value
|
|
1138
|
+
},
|
|
1139
|
+
annotations: [
|
|
1140
|
+
initialSync,
|
|
1141
|
+
reconcileAnnotation.of(true)
|
|
1142
|
+
]
|
|
1143
|
+
});
|
|
1049
1144
|
}
|
|
1050
1145
|
});
|
|
1051
1146
|
}
|
|
@@ -1096,10 +1191,7 @@ var awareness = (provider = dummyProvider) => {
|
|
|
1096
1191
|
];
|
|
1097
1192
|
};
|
|
1098
1193
|
var RemoteSelectionsDecorator = class {
|
|
1099
|
-
_ctx = new Context(void 0, {
|
|
1100
|
-
F: __dxlog_file5,
|
|
1101
|
-
L: 80
|
|
1102
|
-
});
|
|
1194
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 33 });
|
|
1103
1195
|
_cursorConverter;
|
|
1104
1196
|
_provider;
|
|
1105
1197
|
_lastAnchor;
|
|
@@ -1330,10 +1422,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1330
1422
|
this._info = info;
|
|
1331
1423
|
}
|
|
1332
1424
|
open() {
|
|
1333
|
-
this._ctx = new Context2(void 0, {
|
|
1334
|
-
F: __dxlog_file6,
|
|
1335
|
-
L: 57
|
|
1336
|
-
});
|
|
1425
|
+
this._ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 28 });
|
|
1337
1426
|
this._postTask = new DeferredTask(this._ctx, async () => {
|
|
1338
1427
|
if (this._localState) {
|
|
1339
1428
|
await this._messenger.postMessage(this._channel, {
|
|
@@ -1360,12 +1449,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1360
1449
|
}).catch((err) => {
|
|
1361
1450
|
log5.debug("failed to query awareness", {
|
|
1362
1451
|
err
|
|
1363
|
-
}, {
|
|
1364
|
-
F: __dxlog_file6,
|
|
1365
|
-
L: 91,
|
|
1366
|
-
S: this,
|
|
1367
|
-
C: (f, a) => f(...a)
|
|
1368
|
-
});
|
|
1452
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 57, S: this });
|
|
1369
1453
|
});
|
|
1370
1454
|
}
|
|
1371
1455
|
close() {
|
|
@@ -1377,15 +1461,7 @@ var SpaceAwarenessProvider = class {
|
|
|
1377
1461
|
return Array.from(this._remoteStates.values());
|
|
1378
1462
|
}
|
|
1379
1463
|
update(position) {
|
|
1380
|
-
invariant(this._postTask, void 0, {
|
|
1381
|
-
F: __dxlog_file6,
|
|
1382
|
-
L: 106,
|
|
1383
|
-
S: this,
|
|
1384
|
-
A: [
|
|
1385
|
-
"this._postTask",
|
|
1386
|
-
""
|
|
1387
|
-
]
|
|
1388
|
-
});
|
|
1464
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 71, S: this, A: ["this._postTask", ""] });
|
|
1389
1465
|
this._localState = {
|
|
1390
1466
|
peerId: this._peerId,
|
|
1391
1467
|
position,
|
|
@@ -1394,27 +1470,11 @@ var SpaceAwarenessProvider = class {
|
|
|
1394
1470
|
this._postTask.schedule();
|
|
1395
1471
|
}
|
|
1396
1472
|
_handleQueryMessage() {
|
|
1397
|
-
invariant(this._postTask, void 0, {
|
|
1398
|
-
F: __dxlog_file6,
|
|
1399
|
-
L: 117,
|
|
1400
|
-
S: this,
|
|
1401
|
-
A: [
|
|
1402
|
-
"this._postTask",
|
|
1403
|
-
""
|
|
1404
|
-
]
|
|
1405
|
-
});
|
|
1473
|
+
invariant(this._postTask, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 80, S: this, A: ["this._postTask", ""] });
|
|
1406
1474
|
this._postTask.schedule();
|
|
1407
1475
|
}
|
|
1408
1476
|
_handlePostMessage(message) {
|
|
1409
|
-
invariant(message.kind === "post", void 0, {
|
|
1410
|
-
F: __dxlog_file6,
|
|
1411
|
-
L: 122,
|
|
1412
|
-
S: this,
|
|
1413
|
-
A: [
|
|
1414
|
-
"message.kind === 'post'",
|
|
1415
|
-
""
|
|
1416
|
-
]
|
|
1417
|
-
});
|
|
1477
|
+
invariant(message.kind === "post", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file6, L: 84, S: this, A: ["message.kind === 'post'", ""] });
|
|
1418
1478
|
this._remoteStates.set(message.state.peerId, message.state);
|
|
1419
1479
|
this.remoteStateChange.emit();
|
|
1420
1480
|
}
|
|
@@ -1543,15 +1603,7 @@ var Blaster = class {
|
|
|
1543
1603
|
return this._node;
|
|
1544
1604
|
}
|
|
1545
1605
|
initialize() {
|
|
1546
|
-
invariant2(!this._canvas && !this._ctx, void 0, {
|
|
1547
|
-
F: __dxlog_file7,
|
|
1548
|
-
L: 142,
|
|
1549
|
-
S: this,
|
|
1550
|
-
A: [
|
|
1551
|
-
"!this._canvas && !this._ctx",
|
|
1552
|
-
""
|
|
1553
|
-
]
|
|
1554
|
-
});
|
|
1606
|
+
invariant2(!this._canvas && !this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 134, S: this, A: ["!this._canvas && !this._ctx", ""] });
|
|
1555
1607
|
this._canvas = document.createElement("canvas");
|
|
1556
1608
|
this._canvas.id = "code-blast-canvas";
|
|
1557
1609
|
this._canvas.style.position = "absolute";
|
|
@@ -1580,15 +1632,7 @@ var Blaster = class {
|
|
|
1580
1632
|
}
|
|
1581
1633
|
}
|
|
1582
1634
|
start() {
|
|
1583
|
-
invariant2(this._canvas && this._ctx, void 0, {
|
|
1584
|
-
F: __dxlog_file7,
|
|
1585
|
-
L: 181,
|
|
1586
|
-
S: this,
|
|
1587
|
-
A: [
|
|
1588
|
-
"this._canvas && this._ctx",
|
|
1589
|
-
""
|
|
1590
|
-
]
|
|
1591
|
-
});
|
|
1635
|
+
invariant2(this._canvas && this._ctx, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file7, L: 166, S: this, A: ["this._canvas && this._ctx", ""] });
|
|
1592
1636
|
this._running = true;
|
|
1593
1637
|
this.loop();
|
|
1594
1638
|
}
|
|
@@ -1823,13 +1867,13 @@ var blocks = () => [
|
|
|
1823
1867
|
];
|
|
1824
1868
|
|
|
1825
1869
|
// src/extensions/bookmarks.ts
|
|
1826
|
-
import { Prec as Prec3, StateEffect as
|
|
1870
|
+
import { Prec as Prec3, StateEffect as StateEffect4, StateField as StateField2 } from "@codemirror/state";
|
|
1827
1871
|
import { keymap as keymap4 } from "@codemirror/view";
|
|
1828
1872
|
import { log as log6 } from "@dxos/log";
|
|
1829
1873
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/bookmarks.ts";
|
|
1830
|
-
var addBookmark =
|
|
1831
|
-
var removeBookmark =
|
|
1832
|
-
var clearBookmarks =
|
|
1874
|
+
var addBookmark = StateEffect4.define();
|
|
1875
|
+
var removeBookmark = StateEffect4.define();
|
|
1876
|
+
var clearBookmarks = StateEffect4.define();
|
|
1833
1877
|
var bookmarks = () => {
|
|
1834
1878
|
return [
|
|
1835
1879
|
bookmarksField,
|
|
@@ -1838,12 +1882,7 @@ var bookmarks = () => {
|
|
|
1838
1882
|
key: "Mod-ArrowUp",
|
|
1839
1883
|
run: (view) => {
|
|
1840
1884
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1841
|
-
log6("up", bookmarks2, {
|
|
1842
|
-
F: __dxlog_file8,
|
|
1843
|
-
L: 29,
|
|
1844
|
-
S: void 0,
|
|
1845
|
-
C: (f, a) => f(...a)
|
|
1846
|
-
});
|
|
1885
|
+
log6("up", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 18, S: void 0 });
|
|
1847
1886
|
return true;
|
|
1848
1887
|
}
|
|
1849
1888
|
},
|
|
@@ -1851,12 +1890,7 @@ var bookmarks = () => {
|
|
|
1851
1890
|
key: "Mod-ArrowDown",
|
|
1852
1891
|
run: (view) => {
|
|
1853
1892
|
const bookmarks2 = view.state.field(bookmarksField);
|
|
1854
|
-
log6("down", bookmarks2, {
|
|
1855
|
-
F: __dxlog_file8,
|
|
1856
|
-
L: 37,
|
|
1857
|
-
S: void 0,
|
|
1858
|
-
C: (f, a) => f(...a)
|
|
1859
|
-
});
|
|
1893
|
+
log6("down", bookmarks2, { "~LogMeta": "~LogMeta", F: __dxlog_file8, L: 26, S: void 0 });
|
|
1860
1894
|
return true;
|
|
1861
1895
|
}
|
|
1862
1896
|
}
|
|
@@ -1893,7 +1927,7 @@ var bookmarksField = StateField2.define({
|
|
|
1893
1927
|
|
|
1894
1928
|
// src/extensions/comments.ts
|
|
1895
1929
|
import { invertedEffects } from "@codemirror/commands";
|
|
1896
|
-
import { StateEffect as
|
|
1930
|
+
import { StateEffect as StateEffect5, StateField as StateField3 } from "@codemirror/state";
|
|
1897
1931
|
import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin10, hoverTooltip, keymap as keymap6 } from "@codemirror/view";
|
|
1898
1932
|
import sortBy from "lodash.sortby";
|
|
1899
1933
|
import { debounce as debounce2 } from "@dxos/async";
|
|
@@ -1908,7 +1942,7 @@ import { invariant as invariant3 } from "@dxos/invariant";
|
|
|
1908
1942
|
import { isTruthy } from "@dxos/util";
|
|
1909
1943
|
var __dxlog_file9 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/selection.ts";
|
|
1910
1944
|
var documentId = singleValueFacet();
|
|
1911
|
-
var stateRestoreAnnotation = "dxos.
|
|
1945
|
+
var stateRestoreAnnotation = "org.dxos.cm.state-restore";
|
|
1912
1946
|
var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1913
1947
|
return {
|
|
1914
1948
|
selection,
|
|
@@ -1921,28 +1955,12 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
1921
1955
|
};
|
|
1922
1956
|
var createEditorStateStore = (keyPrefix) => ({
|
|
1923
1957
|
getState: (id) => {
|
|
1924
|
-
invariant3(id, void 0, {
|
|
1925
|
-
F: __dxlog_file9,
|
|
1926
|
-
L: 47,
|
|
1927
|
-
S: void 0,
|
|
1928
|
-
A: [
|
|
1929
|
-
"id",
|
|
1930
|
-
""
|
|
1931
|
-
]
|
|
1932
|
-
});
|
|
1958
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 26, S: void 0, A: ["id", ""] });
|
|
1933
1959
|
const state = localStorage.getItem(`${keyPrefix}/${id}`);
|
|
1934
1960
|
return state ? JSON.parse(state) : void 0;
|
|
1935
1961
|
},
|
|
1936
1962
|
setState: (id, state) => {
|
|
1937
|
-
invariant3(id, void 0, {
|
|
1938
|
-
F: __dxlog_file9,
|
|
1939
|
-
L: 53,
|
|
1940
|
-
S: void 0,
|
|
1941
|
-
A: [
|
|
1942
|
-
"id",
|
|
1943
|
-
""
|
|
1944
|
-
]
|
|
1945
|
-
});
|
|
1963
|
+
invariant3(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file9, L: 31, S: void 0, A: ["id", ""] });
|
|
1946
1964
|
localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
|
|
1947
1965
|
}
|
|
1948
1966
|
});
|
|
@@ -1995,9 +2013,9 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
|
1995
2013
|
|
|
1996
2014
|
// src/extensions/comments.ts
|
|
1997
2015
|
var __dxlog_file10 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/comments.ts";
|
|
1998
|
-
var setComments =
|
|
1999
|
-
var setSelection =
|
|
2000
|
-
var setCommentState =
|
|
2016
|
+
var setComments = StateEffect5.define();
|
|
2017
|
+
var setSelection = StateEffect5.define();
|
|
2018
|
+
var setCommentState = StateEffect5.define();
|
|
2001
2019
|
var commentsState = StateField3.define({
|
|
2002
2020
|
create: (state) => ({
|
|
2003
2021
|
id: state.facet(documentId),
|
|
@@ -2064,12 +2082,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2064
2082
|
const decorations2 = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
2065
2083
|
const range = comment.range;
|
|
2066
2084
|
if (!range) {
|
|
2067
|
-
log7.warn("Invalid range:", range, {
|
|
2068
|
-
F: __dxlog_file10,
|
|
2069
|
-
L: 140,
|
|
2070
|
-
S: void 0,
|
|
2071
|
-
C: (f, a) => f(...a)
|
|
2072
|
-
});
|
|
2085
|
+
log7.warn("Invalid range:", range, { "~LogMeta": "~LogMeta", F: __dxlog_file10, L: 93, S: void 0 });
|
|
2073
2086
|
return void 0;
|
|
2074
2087
|
} else if (range.from === range.to) {
|
|
2075
2088
|
return void 0;
|
|
@@ -2079,7 +2092,7 @@ var commentsDecorations = EditorView11.decorations.compute([
|
|
|
2079
2092
|
}).filter(isNonNullable);
|
|
2080
2093
|
return Decoration7.set(decorations2);
|
|
2081
2094
|
});
|
|
2082
|
-
var commentClickedEffect =
|
|
2095
|
+
var commentClickedEffect = StateEffect5.define();
|
|
2083
2096
|
var handleCommentClick = EditorView11.domEventHandlers({
|
|
2084
2097
|
click: (event, view) => {
|
|
2085
2098
|
let target = event.target;
|
|
@@ -2182,10 +2195,10 @@ var trackPastedComments = (onUpdate) => {
|
|
|
2182
2195
|
const { comments: comments2 } = update2.startState.field(commentsState);
|
|
2183
2196
|
const exists = comments2.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);
|
|
2184
2197
|
if (!exists) {
|
|
2185
|
-
const
|
|
2198
|
+
const cursor = Cursor.getCursorFromRange(update2.state, comment);
|
|
2186
2199
|
onUpdate({
|
|
2187
2200
|
id: comment.id,
|
|
2188
|
-
cursor
|
|
2201
|
+
cursor
|
|
2189
2202
|
});
|
|
2190
2203
|
}
|
|
2191
2204
|
}
|
|
@@ -2197,7 +2210,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
|
2197
2210
|
from: changes.mapPos(comment.from, 1),
|
|
2198
2211
|
to: changes.mapPos(comment.to, 1)
|
|
2199
2212
|
});
|
|
2200
|
-
var restoreCommentEffect =
|
|
2213
|
+
var restoreCommentEffect = StateEffect5.define({
|
|
2201
2214
|
map: mapTrackedComment
|
|
2202
2215
|
});
|
|
2203
2216
|
var createComment = (view) => {
|
|
@@ -2214,13 +2227,13 @@ var createComment = (view) => {
|
|
|
2214
2227
|
}
|
|
2215
2228
|
});
|
|
2216
2229
|
}
|
|
2217
|
-
const
|
|
2230
|
+
const cursor = Cursor.getCursorFromRange(view.state, {
|
|
2218
2231
|
from,
|
|
2219
2232
|
to
|
|
2220
2233
|
});
|
|
2221
|
-
if (
|
|
2234
|
+
if (cursor) {
|
|
2222
2235
|
options.onCreate?.({
|
|
2223
|
-
cursor
|
|
2236
|
+
cursor,
|
|
2224
2237
|
from,
|
|
2225
2238
|
location: view.coordsAtPos(from)
|
|
2226
2239
|
});
|
|
@@ -2461,7 +2474,7 @@ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap }
|
|
|
2461
2474
|
import { HighlightStyle, bracketMatching, syntaxHighlighting } from "@codemirror/language";
|
|
2462
2475
|
import { searchKeymap } from "@codemirror/search";
|
|
2463
2476
|
import { EditorState } from "@codemirror/state";
|
|
2464
|
-
import { EditorView as
|
|
2477
|
+
import { EditorView as EditorView16, ViewPlugin as ViewPlugin12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap7, lineNumbers, placeholder as placeholder2 } from "@codemirror/view";
|
|
2465
2478
|
import { vscodeDarkStyle, vscodeLightStyle } from "@uiw/codemirror-theme-vscode";
|
|
2466
2479
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
2467
2480
|
import { generateName } from "@dxos/display-name";
|
|
@@ -2473,28 +2486,28 @@ import { EditorView as EditorView13 } from "@codemirror/view";
|
|
|
2473
2486
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2474
2487
|
var headings = {
|
|
2475
2488
|
1: {
|
|
2476
|
-
className: "text-
|
|
2477
|
-
fontSize: "var(--text-
|
|
2489
|
+
className: "text-3xl",
|
|
2490
|
+
fontSize: "var(--text-3xl)",
|
|
2478
2491
|
lineHeight: "var(--text-4xl--line-height)"
|
|
2479
2492
|
},
|
|
2480
2493
|
2: {
|
|
2481
|
-
className: "text-
|
|
2482
|
-
fontSize: "var(--text-
|
|
2494
|
+
className: "text-2xl",
|
|
2495
|
+
fontSize: "var(--text-2xl)",
|
|
2483
2496
|
lineHeight: "var(--text-3xl--line-height)"
|
|
2484
2497
|
},
|
|
2485
2498
|
3: {
|
|
2486
|
-
className: "text-
|
|
2487
|
-
fontSize: "var(--text-
|
|
2499
|
+
className: "text-xl",
|
|
2500
|
+
fontSize: "var(--text-xl)",
|
|
2488
2501
|
lineHeight: "var(--text-2xl--line-height)"
|
|
2489
2502
|
},
|
|
2490
2503
|
4: {
|
|
2491
|
-
className: "text-
|
|
2492
|
-
fontSize: "var(--text-
|
|
2504
|
+
className: "text-lg",
|
|
2505
|
+
fontSize: "var(--text-lg)",
|
|
2493
2506
|
lineHeight: "var(--text-xl--line-height)"
|
|
2494
2507
|
},
|
|
2495
2508
|
5: {
|
|
2496
|
-
className: "text-
|
|
2497
|
-
fontSize: "var(--text-
|
|
2509
|
+
className: "text-base",
|
|
2510
|
+
fontSize: "var(--text-base)",
|
|
2498
2511
|
lineHeight: "var(--text-lg--line-height)"
|
|
2499
2512
|
},
|
|
2500
2513
|
6: {
|
|
@@ -2503,20 +2516,20 @@ var headings = {
|
|
|
2503
2516
|
lineHeight: "var(--text-base--line-height)"
|
|
2504
2517
|
}
|
|
2505
2518
|
};
|
|
2519
|
+
var fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
|
|
2520
|
+
var fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
|
|
2506
2521
|
var markdownTheme = {
|
|
2507
|
-
code: "font-mono
|
|
2508
|
-
codeMark: "font-mono
|
|
2509
|
-
mark: "
|
|
2522
|
+
code: "font-mono! cm-code-inline",
|
|
2523
|
+
codeMark: "font-mono! cm-code-mark",
|
|
2524
|
+
mark: "font-mono!",
|
|
2510
2525
|
heading: (level) => ({
|
|
2511
|
-
className: mx3(headings[level].className, "font-light text-cm-heading"),
|
|
2526
|
+
className: mx3(headings[level].className, "font-light text-(--color-cm-heading-number)"),
|
|
2512
2527
|
color: "var(--color-cm-heading) !important",
|
|
2513
2528
|
lineHeight: headings[level].lineHeight,
|
|
2514
2529
|
fontSize: headings[level].fontSize,
|
|
2515
2530
|
fontWeight: "100 !important"
|
|
2516
2531
|
})
|
|
2517
2532
|
};
|
|
2518
|
-
var fontBody = "Inter Variable, ui-sans-serif, system-ui, sans-serif";
|
|
2519
|
-
var fontMono = "JetBrains Mono Variable, ui-monospace, Cascadia Code, Source Code Pro, monospace";
|
|
2520
2533
|
var baseTheme = EditorView13.baseTheme({
|
|
2521
2534
|
/**
|
|
2522
2535
|
* Outer frame.
|
|
@@ -2529,12 +2542,21 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2529
2542
|
* Scroller
|
|
2530
2543
|
*/
|
|
2531
2544
|
".cm-scroller": {
|
|
2532
|
-
|
|
2545
|
+
// Browser scroll-anchoring: see comment in `scroller.ts`. `auto` lets the browser pin a
|
|
2546
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
2547
|
+
// open/close) don't jump the user's view.
|
|
2548
|
+
overflowAnchor: "auto"
|
|
2533
2549
|
},
|
|
2534
2550
|
".cm-scroller::-webkit-scrollbar": {
|
|
2535
|
-
width: "8px"
|
|
2551
|
+
width: "var(--scrollbar-size,8px)",
|
|
2552
|
+
height: "var(--scrollbar-size,8px)"
|
|
2553
|
+
},
|
|
2554
|
+
".cm-scroller::-webkit-scrollbar-corner": {
|
|
2555
|
+
background: "transparent"
|
|
2556
|
+
},
|
|
2557
|
+
".cm-scroller::-webkit-scrollbar-track": {
|
|
2558
|
+
background: "transparent"
|
|
2536
2559
|
},
|
|
2537
|
-
".cm-scroller::-webkit-scrollbar-track": {},
|
|
2538
2560
|
".cm-scroller::-webkit-scrollbar-thumb": {
|
|
2539
2561
|
background: "transparent",
|
|
2540
2562
|
transition: "background 0.15s"
|
|
@@ -2548,7 +2570,6 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2548
2570
|
*/
|
|
2549
2571
|
".cm-content": {
|
|
2550
2572
|
padding: "unset",
|
|
2551
|
-
lineHeight: "24px",
|
|
2552
2573
|
color: "unset"
|
|
2553
2574
|
},
|
|
2554
2575
|
/**
|
|
@@ -2579,9 +2600,16 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2579
2600
|
* Line.
|
|
2580
2601
|
*/
|
|
2581
2602
|
".cm-line": {
|
|
2582
|
-
lineHeight:
|
|
2603
|
+
lineHeight: 1.5,
|
|
2583
2604
|
paddingInline: 0
|
|
2584
2605
|
},
|
|
2606
|
+
/**
|
|
2607
|
+
* Force all inline children to inherit line-height to prevent monospace font metrics
|
|
2608
|
+
* (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
|
|
2609
|
+
*/
|
|
2610
|
+
".cm-line *": {
|
|
2611
|
+
lineHeight: "inherit"
|
|
2612
|
+
},
|
|
2585
2613
|
".cm-activeLine": {
|
|
2586
2614
|
background: "var(--color-cm-active-line)"
|
|
2587
2615
|
},
|
|
@@ -2663,12 +2691,12 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2663
2691
|
padding: "4px"
|
|
2664
2692
|
},
|
|
2665
2693
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
2666
|
-
background: "var(--color-
|
|
2667
|
-
color: "var(--color-base-
|
|
2694
|
+
background: "var(--color-current-surface)",
|
|
2695
|
+
color: "var(--color-base-foreground)"
|
|
2668
2696
|
},
|
|
2669
2697
|
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2670
2698
|
paddingLeft: "4px !important",
|
|
2671
|
-
color: "var(--color-base-
|
|
2699
|
+
color: "var(--color-base-foreground)"
|
|
2672
2700
|
},
|
|
2673
2701
|
/**
|
|
2674
2702
|
* Completion info.
|
|
@@ -2687,7 +2715,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2687
2715
|
padding: "0 4px"
|
|
2688
2716
|
},
|
|
2689
2717
|
".cm-completionMatchedText": {
|
|
2690
|
-
color: "var(--color-base-
|
|
2718
|
+
color: "var(--color-base-foreground)",
|
|
2691
2719
|
textDecoration: "none !important"
|
|
2692
2720
|
},
|
|
2693
2721
|
/**
|
|
@@ -2722,7 +2750,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2722
2750
|
backgroundColor: "var(--color-input-surface)"
|
|
2723
2751
|
},
|
|
2724
2752
|
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2725
|
-
outline: "1px solid var(--color-
|
|
2753
|
+
outline: "1px solid var(--color-focus-ring-subtle)"
|
|
2726
2754
|
},
|
|
2727
2755
|
".cm-panel label": {
|
|
2728
2756
|
display: "inline-flex",
|
|
@@ -2735,7 +2763,7 @@ var baseTheme = EditorView13.baseTheme({
|
|
|
2735
2763
|
height: "8px",
|
|
2736
2764
|
marginRight: "6px !important",
|
|
2737
2765
|
padding: "2px !important",
|
|
2738
|
-
color: "var(--color-
|
|
2766
|
+
color: "var(--color-focus-ring-subtle)"
|
|
2739
2767
|
},
|
|
2740
2768
|
".cm-panel button": {
|
|
2741
2769
|
"&:hover": {
|
|
@@ -2759,10 +2787,9 @@ var editorGutter = EditorView13.theme({
|
|
|
2759
2787
|
}
|
|
2760
2788
|
});
|
|
2761
2789
|
var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
2762
|
-
//
|
|
2790
|
+
// Main content.
|
|
2763
2791
|
".cm-scroller": {
|
|
2764
|
-
fontFamily: monospace ? fontMono : fontBody
|
|
2765
|
-
fontSize: "16px"
|
|
2792
|
+
fontFamily: monospace ? fontMono : fontBody
|
|
2766
2793
|
},
|
|
2767
2794
|
// Maintain defaults for UI components.
|
|
2768
2795
|
".cm-content, .cm-gutters, .cm-panel": {
|
|
@@ -2772,9 +2799,9 @@ var createFontTheme = ({ monospace } = {}) => EditorView13.theme({
|
|
|
2772
2799
|
});
|
|
2773
2800
|
|
|
2774
2801
|
// src/extensions/focus.ts
|
|
2775
|
-
import { StateEffect as
|
|
2802
|
+
import { StateEffect as StateEffect6, StateField as StateField5 } from "@codemirror/state";
|
|
2776
2803
|
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
2777
|
-
var focusEffect =
|
|
2804
|
+
var focusEffect = StateEffect6.define();
|
|
2778
2805
|
var focusField = StateField5.define({
|
|
2779
2806
|
create: () => false,
|
|
2780
2807
|
update: (value, tr) => {
|
|
@@ -2802,9 +2829,32 @@ var focus = [
|
|
|
2802
2829
|
})
|
|
2803
2830
|
];
|
|
2804
2831
|
|
|
2832
|
+
// src/extensions/scroll-past-end.ts
|
|
2833
|
+
import { EditorView as EditorView15, ViewPlugin as ViewPlugin11 } from "@codemirror/view";
|
|
2834
|
+
var scrollPastEndPlugin = ViewPlugin11.fromClass(class {
|
|
2835
|
+
height = 1e3;
|
|
2836
|
+
attrs = {
|
|
2837
|
+
style: "padding-bottom: 1000px"
|
|
2838
|
+
};
|
|
2839
|
+
update({ view }) {
|
|
2840
|
+
const lastLineBlock = view.lineBlockAt(view.state.doc.length);
|
|
2841
|
+
const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;
|
|
2842
|
+
if (height >= 0 && height !== this.height) {
|
|
2843
|
+
this.height = height;
|
|
2844
|
+
this.attrs = {
|
|
2845
|
+
style: `padding-bottom: ${height}px`
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
});
|
|
2850
|
+
var scrollPastEnd = () => [
|
|
2851
|
+
scrollPastEndPlugin,
|
|
2852
|
+
EditorView15.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null)
|
|
2853
|
+
];
|
|
2854
|
+
|
|
2805
2855
|
// src/extensions/factories.ts
|
|
2806
2856
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/factories.ts";
|
|
2807
|
-
var tabbable =
|
|
2857
|
+
var tabbable = EditorView16.contentAttributes.of({
|
|
2808
2858
|
tabindex: "0"
|
|
2809
2859
|
});
|
|
2810
2860
|
var filterChars = (chars) => {
|
|
@@ -2857,13 +2907,8 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2857
2907
|
const props = defaultsDeep2({}, propsProp, defaultBasicOptions);
|
|
2858
2908
|
return [
|
|
2859
2909
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
2860
|
-
|
|
2861
|
-
log8.catch(err, void 0, {
|
|
2862
|
-
F: __dxlog_file11,
|
|
2863
|
-
L: 131,
|
|
2864
|
-
S: void 0,
|
|
2865
|
-
C: (f, a) => f(...a)
|
|
2866
|
-
});
|
|
2910
|
+
EditorView16.exceptionSink.of((err) => {
|
|
2911
|
+
log8.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file11, L: 79, S: void 0 });
|
|
2867
2912
|
}),
|
|
2868
2913
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2869
2914
|
props.bracketMatching && bracketMatching(),
|
|
@@ -2872,7 +2917,7 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2872
2917
|
props.drawSelection && drawSelection({
|
|
2873
2918
|
cursorBlinkRate: 1200
|
|
2874
2919
|
}),
|
|
2875
|
-
props.editable !== void 0 &&
|
|
2920
|
+
props.editable !== void 0 && EditorView16.editable.of(props.editable),
|
|
2876
2921
|
props.focus && focus,
|
|
2877
2922
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2878
2923
|
props.history && history(),
|
|
@@ -2880,9 +2925,16 @@ var createBasicExtensions = (propsProp) => {
|
|
|
2880
2925
|
lineNumbers(),
|
|
2881
2926
|
editorGutter
|
|
2882
2927
|
],
|
|
2883
|
-
props.lineWrapping &&
|
|
2928
|
+
props.lineWrapping && EditorView16.lineWrapping,
|
|
2884
2929
|
props.placeholder && placeholder2(props.placeholder),
|
|
2885
2930
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
|
2931
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
2932
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
2933
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
2934
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
2935
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
2936
|
+
// depend on being able to populate the doc themselves.
|
|
2937
|
+
props.readOnly && EditorState.transactionFilter.of((tr) => tr.docChanged && (tr.isUserEvent("input") || tr.isUserEvent("delete") || tr.isUserEvent("undo") || tr.isUserEvent("redo")) ? [] : tr),
|
|
2886
2938
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2887
2939
|
props.tabbable && tabbable,
|
|
2888
2940
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -2925,24 +2977,29 @@ var defaultStyles = {
|
|
|
2925
2977
|
dark: vscodeDarkStyle,
|
|
2926
2978
|
light: vscodeLightStyle
|
|
2927
2979
|
};
|
|
2928
|
-
var createThemeExtensions = ({ monospace,
|
|
2980
|
+
var createThemeExtensions = ({ monospace, scrollbarThin, slots: slotsProp, syntaxHighlighting: syntaxHighlightingProp, themeMode } = {}) => {
|
|
2929
2981
|
const slots = defaultsDeep2({}, slotsProp, defaultThemeSlots);
|
|
2930
2982
|
return [
|
|
2931
2983
|
baseTheme,
|
|
2932
|
-
|
|
2984
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
2933
2985
|
createFontTheme({
|
|
2934
2986
|
monospace
|
|
2935
2987
|
}),
|
|
2936
2988
|
syntaxHighlightingProp && syntaxHighlighting(HighlightStyle.define(themeMode === "dark" ? defaultStyles.dark : defaultStyles.light)),
|
|
2937
|
-
slots.editor?.className &&
|
|
2989
|
+
slots.editor?.className && EditorView16.editorAttributes.of({
|
|
2938
2990
|
class: slots.editor.className
|
|
2939
2991
|
}),
|
|
2940
|
-
slots.content?.className &&
|
|
2992
|
+
slots.content?.className && EditorView16.contentAttributes.of({
|
|
2941
2993
|
class: slots.content.className
|
|
2942
2994
|
}),
|
|
2943
|
-
slots.
|
|
2995
|
+
(slots.scroller?.className || scrollbarThin) && ViewPlugin12.fromClass(class {
|
|
2944
2996
|
constructor(view) {
|
|
2945
|
-
|
|
2997
|
+
if (slots.scroller?.className) {
|
|
2998
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
2999
|
+
}
|
|
3000
|
+
if (scrollbarThin) {
|
|
3001
|
+
view.scrollDOM.style.setProperty("--scrollbar-size", "4px");
|
|
3002
|
+
}
|
|
2946
3003
|
}
|
|
2947
3004
|
})
|
|
2948
3005
|
].filter(isTruthy2);
|
|
@@ -2971,7 +3028,7 @@ var createDataExtensions = ({ id, text, messenger, identity }) => {
|
|
|
2971
3028
|
|
|
2972
3029
|
// src/extensions/folding.ts
|
|
2973
3030
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2974
|
-
import { EditorView as
|
|
3031
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
2975
3032
|
import { Domino as Domino2, mx as mx4 } from "@dxos/ui";
|
|
2976
3033
|
var folding = () => {
|
|
2977
3034
|
return [
|
|
@@ -2979,13 +3036,14 @@ var folding = () => {
|
|
|
2979
3036
|
placeholderDOM: () => Domino2.of("span").root
|
|
2980
3037
|
}),
|
|
2981
3038
|
foldGutter({
|
|
3039
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
2982
3040
|
markerDOM: (open) => {
|
|
2983
|
-
return Domino2.of("div").classNames("flex h-full justify-center items-center").
|
|
3041
|
+
return Domino2.of("div").classNames("flex h-full justify-center items-center").append(Domino2.of("svg", Domino2.SVG).classNames(mx4("w-4 h-4 cursor-pointer", open && "rotate-90")).append(Domino2.of("use", Domino2.SVG).attributes({
|
|
2984
3042
|
href: Domino2.icon("ph--caret-right--regular")
|
|
2985
3043
|
}))).root;
|
|
2986
3044
|
}
|
|
2987
3045
|
}),
|
|
2988
|
-
|
|
3046
|
+
EditorView17.theme({
|
|
2989
3047
|
".cm-foldGutter": {
|
|
2990
3048
|
opacity: 0.3,
|
|
2991
3049
|
transition: "opacity 0.3s",
|
|
@@ -2999,7 +3057,7 @@ var folding = () => {
|
|
|
2999
3057
|
};
|
|
3000
3058
|
|
|
3001
3059
|
// src/extensions/hashtag.ts
|
|
3002
|
-
import { Decoration as Decoration8, EditorView as
|
|
3060
|
+
import { Decoration as Decoration8, EditorView as EditorView18, MatchDecorator, ViewPlugin as ViewPlugin13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3003
3061
|
import { getHashStyles, mx as mx5 } from "@dxos/ui-theme";
|
|
3004
3062
|
var TagWidget = class extends WidgetType4 {
|
|
3005
3063
|
_text;
|
|
@@ -3020,7 +3078,7 @@ var tagMatcher = new MatchDecorator({
|
|
|
3020
3078
|
})
|
|
3021
3079
|
});
|
|
3022
3080
|
var hashtag = () => [
|
|
3023
|
-
|
|
3081
|
+
ViewPlugin13.fromClass(class {
|
|
3024
3082
|
tags;
|
|
3025
3083
|
constructor(view) {
|
|
3026
3084
|
this.tags = tagMatcher.createDeco(view);
|
|
@@ -3030,11 +3088,11 @@ var hashtag = () => [
|
|
|
3030
3088
|
}
|
|
3031
3089
|
}, {
|
|
3032
3090
|
decorations: (instance) => instance.tags,
|
|
3033
|
-
provide: (plugin) =>
|
|
3091
|
+
provide: (plugin) => EditorView18.atomicRanges.of((view) => {
|
|
3034
3092
|
return view.plugin(plugin)?.tags || Decoration8.none;
|
|
3035
3093
|
})
|
|
3036
3094
|
}),
|
|
3037
|
-
|
|
3095
|
+
EditorView18.theme({
|
|
3038
3096
|
".cm-tag": {
|
|
3039
3097
|
borderRadius: "4px",
|
|
3040
3098
|
marginRight: "6px",
|
|
@@ -3089,18 +3147,18 @@ var schemaLinter = (validate) => (view) => {
|
|
|
3089
3147
|
};
|
|
3090
3148
|
|
|
3091
3149
|
// src/extensions/listener.ts
|
|
3092
|
-
import { EditorView as
|
|
3150
|
+
import { EditorView as EditorView19 } from "@codemirror/view";
|
|
3093
3151
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
3094
3152
|
var listener = ({ onFocus, onChange }) => {
|
|
3095
3153
|
return [
|
|
3096
|
-
onFocus &&
|
|
3154
|
+
onFocus && EditorView19.focusChangeEffect.of((state, focusing) => {
|
|
3097
3155
|
onFocus({
|
|
3098
3156
|
id: state.facet(documentId),
|
|
3099
3157
|
focusing
|
|
3100
3158
|
});
|
|
3101
3159
|
return null;
|
|
3102
3160
|
}),
|
|
3103
|
-
onChange &&
|
|
3161
|
+
onChange && EditorView19.updateListener.of(({ state, docChanged }) => {
|
|
3104
3162
|
if (docChanged) {
|
|
3105
3163
|
onChange({
|
|
3106
3164
|
id: state.facet(documentId),
|
|
@@ -3115,7 +3173,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
3115
3173
|
import { snippet } from "@codemirror/autocomplete";
|
|
3116
3174
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3117
3175
|
import { EditorSelection as EditorSelection2 } from "@codemirror/state";
|
|
3118
|
-
import { EditorView as
|
|
3176
|
+
import { EditorView as EditorView20, keymap as keymap8 } from "@codemirror/view";
|
|
3119
3177
|
import { debounceAndThrottle } from "@dxos/async";
|
|
3120
3178
|
var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
3121
3179
|
var Inline = /* @__PURE__ */ (function(Inline2) {
|
|
@@ -4204,7 +4262,7 @@ var getFormatting = (state) => {
|
|
|
4204
4262
|
};
|
|
4205
4263
|
};
|
|
4206
4264
|
var formattingListener = (onStateChange, delay = 100) => {
|
|
4207
|
-
return
|
|
4265
|
+
return EditorView20.updateListener.of(debounceAndThrottle((update2) => {
|
|
4208
4266
|
if (update2.docChanged || update2.selectionSet) {
|
|
4209
4267
|
onStateChange(getFormatting(update2.state));
|
|
4210
4268
|
}
|
|
@@ -4265,8 +4323,7 @@ import { completionKeymap } from "@codemirror/autocomplete";
|
|
|
4265
4323
|
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
4266
4324
|
import { jsonLanguage } from "@codemirror/lang-json";
|
|
4267
4325
|
import { markdown, markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
4268
|
-
import {
|
|
4269
|
-
import { LanguageDescription, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4326
|
+
import { foldNodeProp, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
4270
4327
|
import { languages } from "@codemirror/language-data";
|
|
4271
4328
|
import { keymap as keymap9 } from "@codemirror/view";
|
|
4272
4329
|
import { isTruthy as isTruthy3 } from "@dxos/util";
|
|
@@ -4276,11 +4333,6 @@ import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
|
4276
4333
|
import { HighlightStyle as HighlightStyle2 } from "@codemirror/language";
|
|
4277
4334
|
import { Tag, styleTags, tags } from "@lezer/highlight";
|
|
4278
4335
|
import { Table } from "@lezer/markdown";
|
|
4279
|
-
var styles4 = {
|
|
4280
|
-
code: "font-mono no-underline! text-cm-code",
|
|
4281
|
-
codeMark: "font-mono text-cm-code-mark",
|
|
4282
|
-
mark: "opacity-50"
|
|
4283
|
-
};
|
|
4284
4336
|
var markdownTags = {
|
|
4285
4337
|
Blockquote: Tag.define(),
|
|
4286
4338
|
CodeMark: Tag.define(),
|
|
@@ -4362,7 +4414,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4362
4414
|
markdownTags.LinkReference,
|
|
4363
4415
|
markdownTags.ListMark
|
|
4364
4416
|
],
|
|
4365
|
-
class:
|
|
4417
|
+
class: markdownTheme.mark
|
|
4366
4418
|
},
|
|
4367
4419
|
// Markdown marks.
|
|
4368
4420
|
{
|
|
@@ -4373,7 +4425,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4373
4425
|
markdownTags.QuoteMark,
|
|
4374
4426
|
markdownTags.EmphasisMark
|
|
4375
4427
|
],
|
|
4376
|
-
class:
|
|
4428
|
+
class: markdownTheme.mark
|
|
4377
4429
|
},
|
|
4378
4430
|
// E.g., code block language (after ```).
|
|
4379
4431
|
{
|
|
@@ -4382,7 +4434,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4382
4434
|
tags.function(tags.variableName),
|
|
4383
4435
|
tags.labelName
|
|
4384
4436
|
],
|
|
4385
|
-
class:
|
|
4437
|
+
class: markdownTheme.codeMark
|
|
4386
4438
|
},
|
|
4387
4439
|
// Fonts.
|
|
4388
4440
|
{
|
|
@@ -4448,7 +4500,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
4448
4500
|
markdownTags.CodeText,
|
|
4449
4501
|
markdownTags.InlineCode
|
|
4450
4502
|
],
|
|
4451
|
-
class:
|
|
4503
|
+
class: markdownTheme.code
|
|
4452
4504
|
},
|
|
4453
4505
|
{
|
|
4454
4506
|
tag: [
|
|
@@ -4478,15 +4530,23 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4478
4530
|
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
4479
4531
|
base: markdownLanguage2,
|
|
4480
4532
|
// Languages for syntax highlighting fenced code blocks.
|
|
4533
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
4481
4534
|
defaultCodeLanguage: jsonLanguage,
|
|
4482
|
-
codeLanguages:
|
|
4535
|
+
codeLanguages: [
|
|
4536
|
+
...options.codeLanguages ?? [],
|
|
4537
|
+
...languages
|
|
4538
|
+
],
|
|
4483
4539
|
// Don't complete HTML tags.
|
|
4484
4540
|
completeHTMLTags: false,
|
|
4485
4541
|
// Parser extensions.
|
|
4486
4542
|
extensions: [
|
|
4487
4543
|
// GFM provided by default.
|
|
4488
4544
|
markdownTagsExtensions,
|
|
4489
|
-
...options.extensions ?? defaultExtensions()
|
|
4545
|
+
...options.extensions ?? defaultExtensions(),
|
|
4546
|
+
// Disable folding for fenced code blocks by overriding foldNodeProp.
|
|
4547
|
+
// Note: returning null from foldService does not prevent syntaxFolding fallback,
|
|
4548
|
+
// so we must override the node prop directly on the FencedCode node type.
|
|
4549
|
+
noFencedCodeFolding
|
|
4490
4550
|
]
|
|
4491
4551
|
}),
|
|
4492
4552
|
// Custom styles.
|
|
@@ -4501,18 +4561,13 @@ var createMarkdownExtensions = (options = {}) => {
|
|
|
4501
4561
|
].filter(isTruthy3))
|
|
4502
4562
|
];
|
|
4503
4563
|
};
|
|
4504
|
-
var
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
]
|
|
4510
|
-
|
|
4511
|
-
"xml",
|
|
4512
|
-
"xhtml"
|
|
4513
|
-
],
|
|
4514
|
-
load: async () => xml()
|
|
4515
|
-
});
|
|
4564
|
+
var noFencedCodeFolding = {
|
|
4565
|
+
props: [
|
|
4566
|
+
foldNodeProp.add({
|
|
4567
|
+
FencedCode: () => null
|
|
4568
|
+
})
|
|
4569
|
+
]
|
|
4570
|
+
};
|
|
4516
4571
|
var defaultExtensions = () => [
|
|
4517
4572
|
noSetExtHeading,
|
|
4518
4573
|
noHtml
|
|
@@ -4532,19 +4587,19 @@ var debugTree = (cb) => StateField6.define({
|
|
|
4532
4587
|
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
4533
4588
|
});
|
|
4534
4589
|
var convertTreeToJson = (state) => {
|
|
4535
|
-
const treeToJson = (
|
|
4590
|
+
const treeToJson = (cursor) => {
|
|
4536
4591
|
const node = {
|
|
4537
|
-
type:
|
|
4538
|
-
from:
|
|
4539
|
-
to:
|
|
4540
|
-
text: state.doc.slice(
|
|
4592
|
+
type: cursor.type.name,
|
|
4593
|
+
from: cursor.from,
|
|
4594
|
+
to: cursor.to,
|
|
4595
|
+
text: state.doc.slice(cursor.from, cursor.to).toString(),
|
|
4541
4596
|
children: []
|
|
4542
4597
|
};
|
|
4543
|
-
if (
|
|
4598
|
+
if (cursor.firstChild()) {
|
|
4544
4599
|
do {
|
|
4545
|
-
node.children.push(treeToJson(
|
|
4546
|
-
} while (
|
|
4547
|
-
|
|
4600
|
+
node.children.push(treeToJson(cursor));
|
|
4601
|
+
} while (cursor.nextSibling());
|
|
4602
|
+
cursor.parent();
|
|
4548
4603
|
}
|
|
4549
4604
|
return node;
|
|
4550
4605
|
};
|
|
@@ -4553,17 +4608,16 @@ var convertTreeToJson = (state) => {
|
|
|
4553
4608
|
|
|
4554
4609
|
// src/extensions/markdown/decorate.ts
|
|
4555
4610
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
4556
|
-
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as
|
|
4557
|
-
import { Decoration as Decoration11, EditorView as
|
|
4611
|
+
import { Prec as Prec4, RangeSetBuilder as RangeSetBuilder5, StateEffect as StateEffect7 } from "@codemirror/state";
|
|
4612
|
+
import { Decoration as Decoration11, EditorView as EditorView24, ViewPlugin as ViewPlugin15, WidgetType as WidgetType7 } from "@codemirror/view";
|
|
4558
4613
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4559
|
-
import { mx as mx6 } from "@dxos/ui-theme";
|
|
4560
4614
|
|
|
4561
4615
|
// src/extensions/markdown/changes.ts
|
|
4562
4616
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
4563
4617
|
import { Transaction as Transaction4 } from "@codemirror/state";
|
|
4564
|
-
import { ViewPlugin as
|
|
4618
|
+
import { ViewPlugin as ViewPlugin14 } from "@codemirror/view";
|
|
4565
4619
|
var adjustChanges = () => {
|
|
4566
|
-
return
|
|
4620
|
+
return ViewPlugin14.fromClass(class {
|
|
4567
4621
|
update(update2) {
|
|
4568
4622
|
const tree = syntaxTree4(update2.state);
|
|
4569
4623
|
const adjustments = [];
|
|
@@ -4705,7 +4759,7 @@ var getValidUrl = (str) => {
|
|
|
4705
4759
|
// src/extensions/markdown/image.ts
|
|
4706
4760
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
4707
4761
|
import { StateField as StateField7 } from "@codemirror/state";
|
|
4708
|
-
import { Decoration as Decoration9, EditorView as
|
|
4762
|
+
import { Decoration as Decoration9, EditorView as EditorView21, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4709
4763
|
var image = (_options = {}) => {
|
|
4710
4764
|
return [
|
|
4711
4765
|
StateField7.define({
|
|
@@ -4716,10 +4770,10 @@ var image = (_options = {}) => {
|
|
|
4716
4770
|
if (!tr.docChanged && !tr.selection) {
|
|
4717
4771
|
return value;
|
|
4718
4772
|
}
|
|
4719
|
-
const
|
|
4773
|
+
const cursor = tr.state.selection.main.head;
|
|
4720
4774
|
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
4721
|
-
let from = Math.min(
|
|
4722
|
-
let to = Math.max(
|
|
4775
|
+
let from = Math.min(cursor, oldCursor);
|
|
4776
|
+
let to = Math.max(cursor, oldCursor);
|
|
4723
4777
|
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
4724
4778
|
from = Math.min(from, fromB);
|
|
4725
4779
|
to = Math.max(to, toB);
|
|
@@ -4733,19 +4787,19 @@ var image = (_options = {}) => {
|
|
|
4733
4787
|
add: buildDecorations(tr.state, from, to)
|
|
4734
4788
|
});
|
|
4735
4789
|
},
|
|
4736
|
-
provide: (field) =>
|
|
4790
|
+
provide: (field) => EditorView21.decorations.from(field)
|
|
4737
4791
|
})
|
|
4738
4792
|
];
|
|
4739
4793
|
};
|
|
4740
4794
|
var buildDecorations = (state, from, to) => {
|
|
4741
4795
|
const decorations2 = [];
|
|
4742
|
-
const
|
|
4796
|
+
const cursor = state.selection.main.head;
|
|
4743
4797
|
syntaxTree5(state).iterate({
|
|
4744
4798
|
enter: (node) => {
|
|
4745
4799
|
if (node.name === "Image") {
|
|
4746
4800
|
const urlNode = node.node.getChild("URL");
|
|
4747
4801
|
if (urlNode) {
|
|
4748
|
-
const hide2 = state.readOnly ||
|
|
4802
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
|
|
4749
4803
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
4750
4804
|
if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
|
|
4751
4805
|
return;
|
|
@@ -4793,10 +4847,10 @@ var ImageWidget = class extends WidgetType5 {
|
|
|
4793
4847
|
};
|
|
4794
4848
|
|
|
4795
4849
|
// src/extensions/markdown/styles.ts
|
|
4796
|
-
import { EditorView as
|
|
4850
|
+
import { EditorView as EditorView22 } from "@codemirror/view";
|
|
4797
4851
|
var bulletListIndentationWidth = 24;
|
|
4798
4852
|
var orderedListIndentationWidth = 36;
|
|
4799
|
-
var formattingStyles =
|
|
4853
|
+
var formattingStyles = EditorView22.theme({
|
|
4800
4854
|
/**
|
|
4801
4855
|
* Horizontal rule.
|
|
4802
4856
|
*/
|
|
@@ -4831,13 +4885,38 @@ var formattingStyles = EditorView21.theme({
|
|
|
4831
4885
|
background: "var(--color-cm-codeblock)",
|
|
4832
4886
|
borderLeft: "2px solid var(--color-cm-separator)",
|
|
4833
4887
|
paddingLeft: "1rem",
|
|
4834
|
-
margin:
|
|
4888
|
+
margin: 0
|
|
4835
4889
|
},
|
|
4836
4890
|
/**
|
|
4837
4891
|
* Code and codeblocks.
|
|
4838
4892
|
*/
|
|
4893
|
+
"& code": {
|
|
4894
|
+
fontFamily: fontMono,
|
|
4895
|
+
color: "var(--color-cm-code)",
|
|
4896
|
+
whiteSpace: "nowrap"
|
|
4897
|
+
},
|
|
4839
4898
|
"& .cm-code": {
|
|
4840
|
-
fontFamily: fontMono
|
|
4899
|
+
fontFamily: fontMono,
|
|
4900
|
+
color: "var(--color-cm-code)"
|
|
4901
|
+
},
|
|
4902
|
+
// Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
|
|
4903
|
+
// Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
|
|
4904
|
+
// so constrain them to the target 24px height.
|
|
4905
|
+
"& .cm-code-inline": {
|
|
4906
|
+
fontFamily: fontMono,
|
|
4907
|
+
height: "24px",
|
|
4908
|
+
// display: 'inline-flex',
|
|
4909
|
+
alignItems: "center",
|
|
4910
|
+
overflow: "hidden",
|
|
4911
|
+
whiteSpace: "nowrap",
|
|
4912
|
+
color: "var(--color-cm-code-inline)"
|
|
4913
|
+
},
|
|
4914
|
+
"& .cm-code-mark": {
|
|
4915
|
+
fontFamily: fontMono,
|
|
4916
|
+
height: "24px",
|
|
4917
|
+
display: "inline-flex",
|
|
4918
|
+
alignItems: "center",
|
|
4919
|
+
overflow: "hidden"
|
|
4841
4920
|
},
|
|
4842
4921
|
"& .cm-codeblock-line": {
|
|
4843
4922
|
background: "var(--color-cm-codeblock)",
|
|
@@ -4869,16 +4948,24 @@ var formattingStyles = EditorView21.theme({
|
|
|
4869
4948
|
*/
|
|
4870
4949
|
".cm-table *": {
|
|
4871
4950
|
fontFamily: fontMono,
|
|
4951
|
+
lineHeight: 1.5,
|
|
4872
4952
|
textDecoration: "none !important"
|
|
4873
4953
|
},
|
|
4874
4954
|
".cm-table-head": {
|
|
4875
4955
|
padding: "2px 16px 2px 0px",
|
|
4956
|
+
overflowWrap: "break-word",
|
|
4957
|
+
whiteSpace: "pre-wrap",
|
|
4958
|
+
wordBreak: "keep-all",
|
|
4876
4959
|
textAlign: "left",
|
|
4877
|
-
|
|
4878
|
-
|
|
4960
|
+
color: "var(--color-subdued)",
|
|
4961
|
+
borderBottom: "1px solid var(--color-cm-separator)"
|
|
4879
4962
|
},
|
|
4880
4963
|
".cm-table-cell": {
|
|
4881
|
-
padding: "2px 16px 2px 0px"
|
|
4964
|
+
padding: "2px 16px 2px 0px",
|
|
4965
|
+
overflowWrap: "break-word",
|
|
4966
|
+
whiteSpace: "pre-wrap",
|
|
4967
|
+
wordBreak: "keep-all",
|
|
4968
|
+
verticalAlign: "top"
|
|
4882
4969
|
},
|
|
4883
4970
|
/**
|
|
4884
4971
|
* Image.
|
|
@@ -4894,12 +4981,12 @@ var formattingStyles = EditorView21.theme({
|
|
|
4894
4981
|
},
|
|
4895
4982
|
".cm-image-with-loader": {
|
|
4896
4983
|
display: "block",
|
|
4897
|
-
opacity:
|
|
4984
|
+
opacity: 0,
|
|
4898
4985
|
transitionDuration: "350ms",
|
|
4899
4986
|
transitionProperty: "opacity"
|
|
4900
4987
|
},
|
|
4901
4988
|
".cm-image-with-loader.cm-loaded-image": {
|
|
4902
|
-
opacity:
|
|
4989
|
+
opacity: 1
|
|
4903
4990
|
},
|
|
4904
4991
|
".cm-image-wrapper": {
|
|
4905
4992
|
"grid-template-columns": "1fr",
|
|
@@ -4918,17 +5005,17 @@ var formattingStyles = EditorView21.theme({
|
|
|
4918
5005
|
// src/extensions/markdown/table.ts
|
|
4919
5006
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4920
5007
|
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField8 } from "@codemirror/state";
|
|
4921
|
-
import { Decoration as Decoration10, EditorView as
|
|
5008
|
+
import { Decoration as Decoration10, EditorView as EditorView23, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
4922
5009
|
var table = (options = {}) => {
|
|
4923
5010
|
return StateField8.define({
|
|
4924
5011
|
create: (state) => update(state, options),
|
|
4925
5012
|
update: (_, tr) => update(tr.state, options),
|
|
4926
|
-
provide: (field) =>
|
|
5013
|
+
provide: (field) => EditorView23.decorations.from(field)
|
|
4927
5014
|
});
|
|
4928
5015
|
};
|
|
4929
5016
|
var update = (state, _options) => {
|
|
4930
5017
|
const builder = new RangeSetBuilder4();
|
|
4931
|
-
const
|
|
5018
|
+
const cursor = state.selection.main.head;
|
|
4932
5019
|
const tables = [];
|
|
4933
5020
|
const getTable = () => tables[tables.length - 1];
|
|
4934
5021
|
const getRow = () => {
|
|
@@ -4966,7 +5053,7 @@ var update = (state, _options) => {
|
|
|
4966
5053
|
}
|
|
4967
5054
|
});
|
|
4968
5055
|
tables.forEach((table2) => {
|
|
4969
|
-
const replace = state.readOnly ||
|
|
5056
|
+
const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4970
5057
|
if (replace) {
|
|
4971
5058
|
builder.add(table2.from, table2.to, Decoration10.replace({
|
|
4972
5059
|
block: true,
|
|
@@ -4980,6 +5067,26 @@ var update = (state, _options) => {
|
|
|
4980
5067
|
});
|
|
4981
5068
|
return builder.finish();
|
|
4982
5069
|
};
|
|
5070
|
+
var renderCellContent = (el, text) => {
|
|
5071
|
+
const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
|
|
5072
|
+
for (const part of parts) {
|
|
5073
|
+
if (part.length > 2 && part.startsWith("`") && part.endsWith("`")) {
|
|
5074
|
+
const code = document.createElement("code");
|
|
5075
|
+
code.textContent = part.slice(1, -1);
|
|
5076
|
+
el.appendChild(code);
|
|
5077
|
+
} else if (part.startsWith("**") && part.endsWith("**") || part.startsWith("__") && part.endsWith("__")) {
|
|
5078
|
+
const strong = document.createElement("strong");
|
|
5079
|
+
strong.textContent = part.slice(2, -2);
|
|
5080
|
+
el.appendChild(strong);
|
|
5081
|
+
} else if (part.startsWith("*") && part.endsWith("*") || part.startsWith("_") && part.endsWith("_")) {
|
|
5082
|
+
const em = document.createElement("em");
|
|
5083
|
+
em.textContent = part.slice(1, -1);
|
|
5084
|
+
el.appendChild(em);
|
|
5085
|
+
} else {
|
|
5086
|
+
el.appendChild(document.createTextNode(part));
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
};
|
|
4983
5090
|
var TableWidget = class extends WidgetType6 {
|
|
4984
5091
|
_table;
|
|
4985
5092
|
constructor(_table) {
|
|
@@ -4999,7 +5106,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
4999
5106
|
this._table.header?.forEach((cell) => {
|
|
5000
5107
|
const th = document.createElement("th");
|
|
5001
5108
|
th.setAttribute("class", "cm-table-head");
|
|
5002
|
-
tr.appendChild(th)
|
|
5109
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
5003
5110
|
});
|
|
5004
5111
|
const body = table2.appendChild(document.createElement("tbody"));
|
|
5005
5112
|
this._table.rows?.forEach((row) => {
|
|
@@ -5007,7 +5114,7 @@ var TableWidget = class extends WidgetType6 {
|
|
|
5007
5114
|
row.forEach((cell) => {
|
|
5008
5115
|
const td = document.createElement("td");
|
|
5009
5116
|
td.setAttribute("class", "cm-table-cell");
|
|
5010
|
-
tr2.appendChild(td)
|
|
5117
|
+
renderCellContent(tr2.appendChild(td), cell);
|
|
5011
5118
|
});
|
|
5012
5119
|
});
|
|
5013
5120
|
return div;
|
|
@@ -5114,10 +5221,10 @@ var fencedCodeLine = Decoration11.line({
|
|
|
5114
5221
|
class: "cm-code cm-codeblock-line"
|
|
5115
5222
|
});
|
|
5116
5223
|
var fencedCodeLineFirst = Decoration11.line({
|
|
5117
|
-
class:
|
|
5224
|
+
class: "cm-code cm-codeblock-line cm-codeblock-start"
|
|
5118
5225
|
});
|
|
5119
5226
|
var fencedCodeLineLast = Decoration11.line({
|
|
5120
|
-
class:
|
|
5227
|
+
class: "cm-code cm-codeblock-line cm-codeblock-end"
|
|
5121
5228
|
});
|
|
5122
5229
|
var commentBlockLine = fencedCodeLine;
|
|
5123
5230
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -5149,15 +5256,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5149
5256
|
const { state } = view;
|
|
5150
5257
|
const headerLevels = [];
|
|
5151
5258
|
const getHeaderLevels = (node, level) => {
|
|
5152
|
-
invariant4(level > 0, void 0, {
|
|
5153
|
-
F: __dxlog_file12,
|
|
5154
|
-
L: 179,
|
|
5155
|
-
S: void 0,
|
|
5156
|
-
A: [
|
|
5157
|
-
"level > 0",
|
|
5158
|
-
""
|
|
5159
|
-
]
|
|
5160
|
-
});
|
|
5259
|
+
invariant4(level > 0, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 160, S: void 0, A: ["level > 0", ""] });
|
|
5161
5260
|
if (level > headerLevels.length) {
|
|
5162
5261
|
const len = headerLevels.length;
|
|
5163
5262
|
headerLevels.length = level;
|
|
@@ -5188,15 +5287,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5188
5287
|
listLevels.pop();
|
|
5189
5288
|
};
|
|
5190
5289
|
const getCurrentListLevel = () => {
|
|
5191
|
-
invariant4(listLevels.length, void 0, {
|
|
5192
|
-
F: __dxlog_file12,
|
|
5193
|
-
L: 201,
|
|
5194
|
-
S: void 0,
|
|
5195
|
-
A: [
|
|
5196
|
-
"listLevels.length",
|
|
5197
|
-
""
|
|
5198
|
-
]
|
|
5199
|
-
});
|
|
5290
|
+
invariant4(listLevels.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file12, L: 192, S: void 0, A: ["listLevels.length", ""] });
|
|
5200
5291
|
return listLevels[listLevels.length - 1];
|
|
5201
5292
|
};
|
|
5202
5293
|
const enterNode = (node) => {
|
|
@@ -5234,7 +5325,7 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5234
5325
|
deco: hide
|
|
5235
5326
|
});
|
|
5236
5327
|
} else {
|
|
5237
|
-
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
|
|
5328
|
+
const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + "). ";
|
|
5238
5329
|
if (num.length) {
|
|
5239
5330
|
atomicDecoRanges.push({
|
|
5240
5331
|
from: mark.from,
|
|
@@ -5417,11 +5508,11 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5417
5508
|
}
|
|
5418
5509
|
decoRanges.push({
|
|
5419
5510
|
from: marks[0].to,
|
|
5420
|
-
to: marks[1].from,
|
|
5511
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
5421
5512
|
deco: Decoration11.mark({
|
|
5422
5513
|
tagName: "a",
|
|
5423
5514
|
attributes: {
|
|
5424
|
-
class: "cm-link",
|
|
5515
|
+
class: options.renderLinkButton ? "cm-link cm-link-with-button" : "cm-link",
|
|
5425
5516
|
href: url,
|
|
5426
5517
|
rel: "noreferrer",
|
|
5427
5518
|
target: "_blank"
|
|
@@ -5499,18 +5590,21 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
|
5499
5590
|
deco.add(from, to, d);
|
|
5500
5591
|
}
|
|
5501
5592
|
const atomicDeco = new RangeSetBuilder5();
|
|
5502
|
-
for (const { from, to, deco:
|
|
5503
|
-
|
|
5593
|
+
for (const { from, to, deco: deco2 } of atomicDecoRanges) {
|
|
5594
|
+
if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
|
|
5595
|
+
continue;
|
|
5596
|
+
}
|
|
5597
|
+
atomicDeco.add(from, to, deco2);
|
|
5504
5598
|
}
|
|
5505
5599
|
return {
|
|
5506
5600
|
deco: deco.finish(),
|
|
5507
5601
|
atomicDeco: atomicDeco.finish()
|
|
5508
5602
|
};
|
|
5509
5603
|
};
|
|
5510
|
-
var forceUpdate =
|
|
5604
|
+
var forceUpdate = StateEffect7.define();
|
|
5511
5605
|
var decorateMarkdown = (options = {}) => {
|
|
5512
5606
|
return [
|
|
5513
|
-
|
|
5607
|
+
ViewPlugin15.fromClass(class {
|
|
5514
5608
|
deco;
|
|
5515
5609
|
atomicDeco;
|
|
5516
5610
|
pendingUpdate;
|
|
@@ -5545,9 +5639,9 @@ var decorateMarkdown = (options = {}) => {
|
|
|
5545
5639
|
}
|
|
5546
5640
|
}, {
|
|
5547
5641
|
provide: (plugin) => [
|
|
5548
|
-
Prec4.low(
|
|
5549
|
-
|
|
5550
|
-
|
|
5642
|
+
Prec4.low(EditorView24.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration11.none)),
|
|
5643
|
+
EditorView24.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none),
|
|
5644
|
+
EditorView24.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration11.none)
|
|
5551
5645
|
]
|
|
5552
5646
|
}),
|
|
5553
5647
|
image(),
|
|
@@ -5615,12 +5709,7 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5615
5709
|
(context) => {
|
|
5616
5710
|
log9.info("completion context", {
|
|
5617
5711
|
context
|
|
5618
|
-
}, {
|
|
5619
|
-
F: __dxlog_file13,
|
|
5620
|
-
L: 27,
|
|
5621
|
-
S: void 0,
|
|
5622
|
-
C: (f, a) => f(...a)
|
|
5623
|
-
});
|
|
5712
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file13, L: 18, S: void 0 });
|
|
5624
5713
|
const match = context.matchBefore(/@(\w+)?/);
|
|
5625
5714
|
if (!match || match.from === match.to && !context.explicit) {
|
|
5626
5715
|
return null;
|
|
@@ -5637,8 +5726,8 @@ var mention = ({ debug, onSearch }) => {
|
|
|
5637
5726
|
};
|
|
5638
5727
|
|
|
5639
5728
|
// src/extensions/modal.ts
|
|
5640
|
-
import { StateEffect as
|
|
5641
|
-
var modalStateEffect =
|
|
5729
|
+
import { StateEffect as StateEffect8, StateField as StateField9 } from "@codemirror/state";
|
|
5730
|
+
var modalStateEffect = StateEffect8.define();
|
|
5642
5731
|
var modalStateField = StateField9.define({
|
|
5643
5732
|
create: () => false,
|
|
5644
5733
|
update: (value, tr) => {
|
|
@@ -5853,15 +5942,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5853
5942
|
break;
|
|
5854
5943
|
}
|
|
5855
5944
|
case "BulletList": {
|
|
5856
|
-
invariant5(current, void 0, {
|
|
5857
|
-
F: __dxlog_file14,
|
|
5858
|
-
L: 219,
|
|
5859
|
-
S: void 0,
|
|
5860
|
-
A: [
|
|
5861
|
-
"current",
|
|
5862
|
-
""
|
|
5863
|
-
]
|
|
5864
|
-
});
|
|
5945
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 169, S: void 0, A: ["current", ""] });
|
|
5865
5946
|
parent = current;
|
|
5866
5947
|
if (current) {
|
|
5867
5948
|
current.lineRange.to = current.node.from;
|
|
@@ -5870,15 +5951,7 @@ var outlinerTree = (_options = {}) => {
|
|
|
5870
5951
|
break;
|
|
5871
5952
|
}
|
|
5872
5953
|
case "ListItem": {
|
|
5873
|
-
invariant5(parent, void 0, {
|
|
5874
|
-
F: __dxlog_file14,
|
|
5875
|
-
L: 228,
|
|
5876
|
-
S: void 0,
|
|
5877
|
-
A: [
|
|
5878
|
-
"parent",
|
|
5879
|
-
""
|
|
5880
|
-
]
|
|
5881
|
-
});
|
|
5954
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 179, S: void 0, A: ["parent", ""] });
|
|
5882
5955
|
const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;
|
|
5883
5956
|
const docRange = {
|
|
5884
5957
|
from: state.doc.lineAt(node.from).from,
|
|
@@ -5912,42 +5985,18 @@ var outlinerTree = (_options = {}) => {
|
|
|
5912
5985
|
break;
|
|
5913
5986
|
}
|
|
5914
5987
|
case "ListMark": {
|
|
5915
|
-
invariant5(current, void 0, {
|
|
5916
|
-
F: __dxlog_file14,
|
|
5917
|
-
L: 272,
|
|
5918
|
-
S: void 0,
|
|
5919
|
-
A: [
|
|
5920
|
-
"current",
|
|
5921
|
-
""
|
|
5922
|
-
]
|
|
5923
|
-
});
|
|
5988
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 219, S: void 0, A: ["current", ""] });
|
|
5924
5989
|
current.type = "bullet";
|
|
5925
5990
|
current.contentRange.from = node.from + "- ".length;
|
|
5926
5991
|
break;
|
|
5927
5992
|
}
|
|
5928
5993
|
case "Task": {
|
|
5929
|
-
invariant5(current, void 0, {
|
|
5930
|
-
F: __dxlog_file14,
|
|
5931
|
-
L: 278,
|
|
5932
|
-
S: void 0,
|
|
5933
|
-
A: [
|
|
5934
|
-
"current",
|
|
5935
|
-
""
|
|
5936
|
-
]
|
|
5937
|
-
});
|
|
5994
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 226, S: void 0, A: ["current", ""] });
|
|
5938
5995
|
current.type = "task";
|
|
5939
5996
|
break;
|
|
5940
5997
|
}
|
|
5941
5998
|
case "TaskMarker": {
|
|
5942
|
-
invariant5(current, void 0, {
|
|
5943
|
-
F: __dxlog_file14,
|
|
5944
|
-
L: 283,
|
|
5945
|
-
S: void 0,
|
|
5946
|
-
A: [
|
|
5947
|
-
"current",
|
|
5948
|
-
""
|
|
5949
|
-
]
|
|
5950
|
-
});
|
|
5999
|
+
invariant5(current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 232, S: void 0, A: ["current", ""] });
|
|
5951
6000
|
current.contentRange.from = node.from + "[ ] ".length;
|
|
5952
6001
|
break;
|
|
5953
6002
|
}
|
|
@@ -5955,29 +6004,13 @@ var outlinerTree = (_options = {}) => {
|
|
|
5955
6004
|
},
|
|
5956
6005
|
leave: (node) => {
|
|
5957
6006
|
if (node.name === "BulletList") {
|
|
5958
|
-
invariant5(parent, void 0, {
|
|
5959
|
-
F: __dxlog_file14,
|
|
5960
|
-
L: 291,
|
|
5961
|
-
S: void 0,
|
|
5962
|
-
A: [
|
|
5963
|
-
"parent",
|
|
5964
|
-
""
|
|
5965
|
-
]
|
|
5966
|
-
});
|
|
6007
|
+
invariant5(parent, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 240, S: void 0, A: ["parent", ""] });
|
|
5967
6008
|
prevSiblings[level--] = void 0;
|
|
5968
6009
|
parent = parent.parent;
|
|
5969
6010
|
}
|
|
5970
6011
|
}
|
|
5971
6012
|
});
|
|
5972
|
-
invariant5(tree, void 0, {
|
|
5973
|
-
F: __dxlog_file14,
|
|
5974
|
-
L: 298,
|
|
5975
|
-
S: void 0,
|
|
5976
|
-
A: [
|
|
5977
|
-
"tree",
|
|
5978
|
-
""
|
|
5979
|
-
]
|
|
5980
|
-
});
|
|
6013
|
+
invariant5(tree, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file14, L: 246, S: void 0, A: ["tree", ""] });
|
|
5981
6014
|
return tree;
|
|
5982
6015
|
};
|
|
5983
6016
|
return [
|
|
@@ -6262,17 +6295,17 @@ var commands = () => keymap11.of([
|
|
|
6262
6295
|
|
|
6263
6296
|
// src/extensions/outliner/outliner.ts
|
|
6264
6297
|
import { Prec as Prec5 } from "@codemirror/state";
|
|
6265
|
-
import { Decoration as Decoration12, EditorView as
|
|
6266
|
-
import { mx as
|
|
6298
|
+
import { Decoration as Decoration12, EditorView as EditorView26, ViewPlugin as ViewPlugin18 } from "@codemirror/view";
|
|
6299
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
6267
6300
|
|
|
6268
6301
|
// src/extensions/outliner/editor.ts
|
|
6269
6302
|
import { EditorSelection as EditorSelection4, EditorState as EditorState2 } from "@codemirror/state";
|
|
6270
|
-
import { ViewPlugin as
|
|
6303
|
+
import { ViewPlugin as ViewPlugin16 } from "@codemirror/view";
|
|
6271
6304
|
import { log as log10 } from "@dxos/log";
|
|
6272
6305
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/outliner/editor.ts";
|
|
6273
6306
|
var LIST_ITEM_REGEX = /^\s*- (\[ \]|\[x\])? /;
|
|
6274
6307
|
var initialize = () => {
|
|
6275
|
-
return
|
|
6308
|
+
return ViewPlugin16.fromClass(class {
|
|
6276
6309
|
constructor(view) {
|
|
6277
6310
|
const first = view.state.doc.lineAt(0);
|
|
6278
6311
|
const text = view.state.sliceDoc(first.from, first.to);
|
|
@@ -6419,35 +6452,20 @@ var editor = () => [
|
|
|
6419
6452
|
text: insert.toString(),
|
|
6420
6453
|
length: insert.length
|
|
6421
6454
|
}
|
|
6422
|
-
}, {
|
|
6423
|
-
F: __dxlog_file15,
|
|
6424
|
-
L: 164,
|
|
6425
|
-
S: void 0,
|
|
6426
|
-
C: (f, a) => f(...a)
|
|
6427
|
-
});
|
|
6455
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 174, S: void 0 });
|
|
6428
6456
|
}
|
|
6429
6457
|
});
|
|
6430
6458
|
if (changes.length > 0) {
|
|
6431
6459
|
log10("modified,", {
|
|
6432
6460
|
changes
|
|
6433
|
-
}, {
|
|
6434
|
-
F: __dxlog_file15,
|
|
6435
|
-
L: 175,
|
|
6436
|
-
S: void 0,
|
|
6437
|
-
C: (f, a) => f(...a)
|
|
6438
|
-
});
|
|
6461
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 196, S: void 0 });
|
|
6439
6462
|
return [
|
|
6440
6463
|
{
|
|
6441
6464
|
changes
|
|
6442
6465
|
}
|
|
6443
6466
|
];
|
|
6444
6467
|
} else if (cancel) {
|
|
6445
|
-
log10("cancel", void 0, {
|
|
6446
|
-
F: __dxlog_file15,
|
|
6447
|
-
L: 178,
|
|
6448
|
-
S: void 0,
|
|
6449
|
-
C: (f, a) => f(...a)
|
|
6450
|
-
});
|
|
6468
|
+
log10("cancel", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file15, L: 205, S: void 0 });
|
|
6451
6469
|
return [];
|
|
6452
6470
|
}
|
|
6453
6471
|
return tr;
|
|
@@ -6455,10 +6473,10 @@ var editor = () => [
|
|
|
6455
6473
|
];
|
|
6456
6474
|
|
|
6457
6475
|
// src/extensions/outliner/menu.ts
|
|
6458
|
-
import { EditorView as
|
|
6476
|
+
import { EditorView as EditorView25, ViewPlugin as ViewPlugin17 } from "@codemirror/view";
|
|
6459
6477
|
import { addEventListener as addEventListener2 } from "@dxos/async";
|
|
6460
6478
|
var menu = (options = {}) => [
|
|
6461
|
-
|
|
6479
|
+
ViewPlugin17.fromClass(class {
|
|
6462
6480
|
view;
|
|
6463
6481
|
tag;
|
|
6464
6482
|
rafId;
|
|
@@ -6520,7 +6538,7 @@ var menu = (options = {}) => [
|
|
|
6520
6538
|
this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
|
|
6521
6539
|
}
|
|
6522
6540
|
}),
|
|
6523
|
-
|
|
6541
|
+
EditorView25.theme({
|
|
6524
6542
|
".cm-popover-trigger": {
|
|
6525
6543
|
position: "fixed",
|
|
6526
6544
|
padding: "0",
|
|
@@ -6556,12 +6574,12 @@ var outliner = (_options = {}) => [
|
|
|
6556
6574
|
listPaddingLeft: 8
|
|
6557
6575
|
}),
|
|
6558
6576
|
// Researve space for menu.
|
|
6559
|
-
|
|
6577
|
+
EditorView26.contentAttributes.of({
|
|
6560
6578
|
class: "w-full !mr-[3rem]"
|
|
6561
6579
|
})
|
|
6562
6580
|
];
|
|
6563
6581
|
var decorations = () => [
|
|
6564
|
-
|
|
6582
|
+
ViewPlugin18.fromClass(class {
|
|
6565
6583
|
decorations = Decoration12.none;
|
|
6566
6584
|
constructor(view) {
|
|
6567
6585
|
this.updateDecorations(view.state, view);
|
|
@@ -6586,7 +6604,7 @@ var decorations = () => [
|
|
|
6586
6604
|
const lineTo = doc.lineAt(item.contentRange.to);
|
|
6587
6605
|
const isSelected = selection.includes(item.index) || item === current;
|
|
6588
6606
|
decorations2.push(Decoration12.line({
|
|
6589
|
-
class:
|
|
6607
|
+
class: mx6("cm-list-item", lineFrom.number === line.number && "cm-list-item-start", lineTo.number === line.number && "cm-list-item-end", isSelected && (hasFocus ? "cm-list-item-focused" : "cm-list-item-selected"))
|
|
6590
6608
|
}).range(line.from, line.from));
|
|
6591
6609
|
}
|
|
6592
6610
|
}
|
|
@@ -6596,7 +6614,7 @@ var decorations = () => [
|
|
|
6596
6614
|
decorations: (v) => v.decorations
|
|
6597
6615
|
}),
|
|
6598
6616
|
// Theme.
|
|
6599
|
-
|
|
6617
|
+
EditorView26.theme(Object.assign({
|
|
6600
6618
|
".cm-list-item": {
|
|
6601
6619
|
borderLeftWidth: "1px",
|
|
6602
6620
|
borderRightWidth: "1px",
|
|
@@ -6621,7 +6639,7 @@ var decorations = () => [
|
|
|
6621
6639
|
marginBottom: "2px"
|
|
6622
6640
|
},
|
|
6623
6641
|
".cm-list-item-focused": {
|
|
6624
|
-
borderColor: "var(--color-
|
|
6642
|
+
borderColor: "var(--color-focus-ring-subtle)"
|
|
6625
6643
|
},
|
|
6626
6644
|
"&:focus-within .cm-list-item-selected": {
|
|
6627
6645
|
borderColor: "var(--color-separator)"
|
|
@@ -6631,28 +6649,57 @@ var decorations = () => [
|
|
|
6631
6649
|
|
|
6632
6650
|
// src/extensions/preview/preview.ts
|
|
6633
6651
|
import { syntaxTree as syntaxTree10 } from "@codemirror/language";
|
|
6634
|
-
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField11 } from "@codemirror/state";
|
|
6635
|
-
import { Decoration as Decoration13, EditorView as
|
|
6652
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateEffect as StateEffect9, StateField as StateField11 } from "@codemirror/state";
|
|
6653
|
+
import { Decoration as Decoration13, EditorView as EditorView27, ViewPlugin as ViewPlugin19, WidgetType as WidgetType8 } from "@codemirror/view";
|
|
6654
|
+
import { DXN, Entity } from "@dxos/echo";
|
|
6655
|
+
var labelResolvedEffect = StateEffect9.define();
|
|
6636
6656
|
var preview = (options = {}) => {
|
|
6657
|
+
const viewRef = {
|
|
6658
|
+
current: void 0
|
|
6659
|
+
};
|
|
6637
6660
|
return [
|
|
6638
6661
|
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
|
6639
6662
|
// "Block decorations may not be specified via plugins".
|
|
6640
6663
|
StateField11.define({
|
|
6641
|
-
create: (state) => buildDecorations3(state, options),
|
|
6664
|
+
create: (state) => buildDecorations3(state, options, viewRef),
|
|
6642
6665
|
update: (decorations2, tr) => {
|
|
6643
|
-
if (tr.docChanged) {
|
|
6644
|
-
return buildDecorations3(tr.state, options);
|
|
6666
|
+
if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {
|
|
6667
|
+
return buildDecorations3(tr.state, options, viewRef);
|
|
6645
6668
|
}
|
|
6646
6669
|
return decorations2.map(tr.changes);
|
|
6647
6670
|
},
|
|
6648
6671
|
provide: (field) => [
|
|
6649
|
-
|
|
6650
|
-
|
|
6672
|
+
EditorView27.decorations.from(field),
|
|
6673
|
+
EditorView27.atomicRanges.of((view) => view.state.field(field))
|
|
6651
6674
|
]
|
|
6675
|
+
}),
|
|
6676
|
+
ViewPlugin19.define((view) => {
|
|
6677
|
+
viewRef.current = view;
|
|
6678
|
+
return {
|
|
6679
|
+
destroy() {
|
|
6680
|
+
viewRef.current = void 0;
|
|
6681
|
+
}
|
|
6682
|
+
};
|
|
6652
6683
|
})
|
|
6653
6684
|
];
|
|
6654
6685
|
};
|
|
6655
|
-
var
|
|
6686
|
+
var resolveLabel = (db, dxnStr, viewRef) => {
|
|
6687
|
+
const dxn = DXN.tryParse(dxnStr);
|
|
6688
|
+
if (!dxn) {
|
|
6689
|
+
return;
|
|
6690
|
+
}
|
|
6691
|
+
const ref = db.makeRef(dxn);
|
|
6692
|
+
const target = ref.target;
|
|
6693
|
+
if (target) {
|
|
6694
|
+
return Entity.getLabel(target);
|
|
6695
|
+
}
|
|
6696
|
+
void ref.tryLoad().then(() => {
|
|
6697
|
+
viewRef.current?.dispatch({
|
|
6698
|
+
effects: labelResolvedEffect.of(void 0)
|
|
6699
|
+
});
|
|
6700
|
+
});
|
|
6701
|
+
};
|
|
6702
|
+
var buildDecorations3 = (state, options, viewRef) => {
|
|
6656
6703
|
const builder = new RangeSetBuilder6();
|
|
6657
6704
|
syntaxTree10(state).iterate({
|
|
6658
6705
|
enter: (node) => {
|
|
@@ -6664,8 +6711,13 @@ var buildDecorations3 = (state, options) => {
|
|
|
6664
6711
|
case "Link": {
|
|
6665
6712
|
const link = getLinkRef(state, node.node);
|
|
6666
6713
|
if (link) {
|
|
6714
|
+
const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : void 0;
|
|
6715
|
+
const displayLink = resolved ? {
|
|
6716
|
+
...link,
|
|
6717
|
+
label: resolved
|
|
6718
|
+
} : link;
|
|
6667
6719
|
builder.add(node.from, node.to, Decoration13.replace({
|
|
6668
|
-
widget: new PreviewInlineWidget(options,
|
|
6720
|
+
widget: new PreviewInlineWidget(options, displayLink),
|
|
6669
6721
|
side: 1
|
|
6670
6722
|
}));
|
|
6671
6723
|
}
|
|
@@ -6757,7 +6809,7 @@ var PreviewBlockWidget = class extends WidgetType8 {
|
|
|
6757
6809
|
};
|
|
6758
6810
|
|
|
6759
6811
|
// src/extensions/replacer.ts
|
|
6760
|
-
import { EditorView as
|
|
6812
|
+
import { EditorView as EditorView28 } from "@codemirror/view";
|
|
6761
6813
|
var defaultReplacements = [
|
|
6762
6814
|
{
|
|
6763
6815
|
input: "--",
|
|
@@ -6820,7 +6872,7 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6820
6872
|
const sortedReplacements = [
|
|
6821
6873
|
...replacements
|
|
6822
6874
|
].sort((a, b) => b.input.length - a.input.length);
|
|
6823
|
-
return
|
|
6875
|
+
return EditorView28.inputHandler.of((view, from, to, insert) => {
|
|
6824
6876
|
if (insert.length !== 1) {
|
|
6825
6877
|
return false;
|
|
6826
6878
|
}
|
|
@@ -6854,12 +6906,69 @@ var replacer = ({ replacements = defaultReplacements } = {}) => {
|
|
|
6854
6906
|
});
|
|
6855
6907
|
};
|
|
6856
6908
|
|
|
6909
|
+
// src/extensions/snippets.ts
|
|
6910
|
+
import { keymap as keymap12 } from "@codemirror/view";
|
|
6911
|
+
var defaultItems = [
|
|
6912
|
+
"hello world!",
|
|
6913
|
+
"this is a test.",
|
|
6914
|
+
"this is [DXOS](https://dxos.org)"
|
|
6915
|
+
];
|
|
6916
|
+
var snippets2 = ({ delay = 75, items = defaultItems } = {}) => {
|
|
6917
|
+
let timer;
|
|
6918
|
+
let index = 0;
|
|
6919
|
+
return [
|
|
6920
|
+
keymap12.of([
|
|
6921
|
+
{
|
|
6922
|
+
// Reset.
|
|
6923
|
+
key: "alt-meta-'",
|
|
6924
|
+
run: () => {
|
|
6925
|
+
clearTimeout(timer);
|
|
6926
|
+
index = 0;
|
|
6927
|
+
return true;
|
|
6928
|
+
}
|
|
6929
|
+
},
|
|
6930
|
+
{
|
|
6931
|
+
// Next snippet.
|
|
6932
|
+
// TODO(burdon): Press 1-9 to select snippet?
|
|
6933
|
+
key: "Shift-Meta-'",
|
|
6934
|
+
run: (view) => {
|
|
6935
|
+
clearTimeout(timer);
|
|
6936
|
+
const text = items[index++];
|
|
6937
|
+
if (index === items?.length) {
|
|
6938
|
+
index = 0;
|
|
6939
|
+
}
|
|
6940
|
+
let offset = 0;
|
|
6941
|
+
const insert = (delayMs = 0) => {
|
|
6942
|
+
timer = setTimeout(() => {
|
|
6943
|
+
const pos = view.state.selection.main.head;
|
|
6944
|
+
view.dispatch({
|
|
6945
|
+
changes: {
|
|
6946
|
+
from: pos,
|
|
6947
|
+
insert: text[offset++]
|
|
6948
|
+
},
|
|
6949
|
+
selection: {
|
|
6950
|
+
anchor: pos + 1
|
|
6951
|
+
}
|
|
6952
|
+
});
|
|
6953
|
+
if (offset < text.length) {
|
|
6954
|
+
insert(Math.random() * delay * (text[offset] === " " ? 2 : 1));
|
|
6955
|
+
}
|
|
6956
|
+
}, delayMs);
|
|
6957
|
+
};
|
|
6958
|
+
insert();
|
|
6959
|
+
return true;
|
|
6960
|
+
}
|
|
6961
|
+
}
|
|
6962
|
+
])
|
|
6963
|
+
];
|
|
6964
|
+
};
|
|
6965
|
+
|
|
6857
6966
|
// src/extensions/submit.ts
|
|
6858
6967
|
import { Prec as Prec6 } from "@codemirror/state";
|
|
6859
|
-
import { keymap as
|
|
6968
|
+
import { keymap as keymap13 } from "@codemirror/view";
|
|
6860
6969
|
var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
6861
6970
|
return [
|
|
6862
|
-
Prec6.highest(
|
|
6971
|
+
Prec6.highest(keymap13.of([
|
|
6863
6972
|
{
|
|
6864
6973
|
key: "Enter",
|
|
6865
6974
|
preventDefault: true,
|
|
@@ -6904,6 +7013,7 @@ var submit = ({ fireIfEmpty = false, onSubmit } = {}) => {
|
|
|
6904
7013
|
// src/extensions/tags/extended-markdown.ts
|
|
6905
7014
|
import { xmlLanguage } from "@codemirror/lang-xml";
|
|
6906
7015
|
import { parseMixed } from "@lezer/common";
|
|
7016
|
+
var escapeRegExpSource = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6907
7017
|
var extendedMarkdown = ({ registry } = {}) => {
|
|
6908
7018
|
return [
|
|
6909
7019
|
createMarkdownExtensions({
|
|
@@ -6915,13 +7025,65 @@ var extendedMarkdown = ({ registry } = {}) => {
|
|
|
6915
7025
|
{
|
|
6916
7026
|
name: "SetextHeading",
|
|
6917
7027
|
parse: () => false
|
|
6918
|
-
}
|
|
7028
|
+
},
|
|
7029
|
+
// Custom XML block parser that keeps registered tags as a single HTMLBlock
|
|
7030
|
+
// even when their content contains blank lines.
|
|
7031
|
+
...xmlBlockParsers(registry)
|
|
6919
7032
|
]
|
|
6920
7033
|
}
|
|
6921
7034
|
]
|
|
6922
7035
|
})
|
|
6923
7036
|
];
|
|
6924
7037
|
};
|
|
7038
|
+
var xmlBlockParsers = (registry) => {
|
|
7039
|
+
const customTags = Object.keys(registry ?? {});
|
|
7040
|
+
if (customTags.length === 0) {
|
|
7041
|
+
return [];
|
|
7042
|
+
}
|
|
7043
|
+
const tagPattern = customTags.map(escapeRegExpSource).join("|");
|
|
7044
|
+
const selfClosePattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/>\\s*$`);
|
|
7045
|
+
const openPattern = new RegExp(`^\\s*<(${tagPattern})(\\s[^>]*)?\\/?>`);
|
|
7046
|
+
return [
|
|
7047
|
+
{
|
|
7048
|
+
name: "XMLBlock",
|
|
7049
|
+
before: "HTMLBlock",
|
|
7050
|
+
parse: (cx, line) => {
|
|
7051
|
+
const match = openPattern.exec(line.text);
|
|
7052
|
+
if (!match) {
|
|
7053
|
+
return false;
|
|
7054
|
+
}
|
|
7055
|
+
if (selfClosePattern.test(line.text)) {
|
|
7056
|
+
const end2 = cx.lineStart + line.text.length;
|
|
7057
|
+
cx.addElement(cx.elt("HTMLBlock", cx.lineStart, end2));
|
|
7058
|
+
cx.nextLine();
|
|
7059
|
+
return true;
|
|
7060
|
+
}
|
|
7061
|
+
if (match[0].trimEnd().endsWith("/>")) {
|
|
7062
|
+
return false;
|
|
7063
|
+
}
|
|
7064
|
+
const tagName = match[1];
|
|
7065
|
+
const closeTag = `</${tagName}>`;
|
|
7066
|
+
const start = cx.lineStart;
|
|
7067
|
+
if (line.text.includes(closeTag)) {
|
|
7068
|
+
cx.addElement(cx.elt("HTMLBlock", start, start + line.text.length));
|
|
7069
|
+
cx.nextLine();
|
|
7070
|
+
return true;
|
|
7071
|
+
}
|
|
7072
|
+
let end = cx.lineStart + line.text.length;
|
|
7073
|
+
while (cx.nextLine()) {
|
|
7074
|
+
end = cx.lineStart + line.text.length;
|
|
7075
|
+
if (line.text.includes(closeTag)) {
|
|
7076
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7077
|
+
cx.nextLine();
|
|
7078
|
+
return true;
|
|
7079
|
+
}
|
|
7080
|
+
}
|
|
7081
|
+
cx.addElement(cx.elt("HTMLBlock", start, end));
|
|
7082
|
+
return true;
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
];
|
|
7086
|
+
};
|
|
6925
7087
|
var mixedParser = (registry) => {
|
|
6926
7088
|
const customTags = Object.keys(registry ?? {});
|
|
6927
7089
|
const tagPattern = new RegExp(`<(${customTags.join("|")})`);
|
|
@@ -6955,219 +7117,793 @@ var mixedParser = (registry) => {
|
|
|
6955
7117
|
});
|
|
6956
7118
|
};
|
|
6957
7119
|
|
|
6958
|
-
// src/extensions/tags/
|
|
6959
|
-
import { StateEffect as
|
|
6960
|
-
import { Decoration as Decoration14, EditorView as
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
var
|
|
6964
|
-
var
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
7120
|
+
// src/extensions/tags/fader.ts
|
|
7121
|
+
import { StateEffect as StateEffect10, StateField as StateField12 } from "@codemirror/state";
|
|
7122
|
+
import { Decoration as Decoration14, EditorView as EditorView29, ViewPlugin as ViewPlugin20 } from "@codemirror/view";
|
|
7123
|
+
var DEFAULT_REMOVAL_DELAY = 5e3;
|
|
7124
|
+
var DEFAULT_COALESCE_WINDOW = 100;
|
|
7125
|
+
var CLEANUP_INTERVAL = 1e3;
|
|
7126
|
+
var fader = (options = {}) => {
|
|
7127
|
+
const removalDelay = DEFAULT_REMOVAL_DELAY;
|
|
7128
|
+
const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;
|
|
7129
|
+
let lastCount = -1;
|
|
7130
|
+
const log12 = (expiries) => {
|
|
7131
|
+
if (expiries.length !== lastCount) {
|
|
7132
|
+
lastCount = expiries.length;
|
|
7133
|
+
}
|
|
7134
|
+
};
|
|
7135
|
+
const dequeue = StateEffect10.define();
|
|
7136
|
+
const fadeField = StateField12.define({
|
|
7137
|
+
create: () => ({
|
|
7138
|
+
decorations: Decoration14.none,
|
|
7139
|
+
expiries: [],
|
|
7140
|
+
batchStart: 0
|
|
7141
|
+
}),
|
|
7142
|
+
update: ({ decorations: decorations2, expiries, batchStart }, tr) => {
|
|
7143
|
+
for (const effect of tr.effects) {
|
|
7144
|
+
if (effect.is(dequeue)) {
|
|
7145
|
+
const now2 = effect.value;
|
|
7146
|
+
let removeCount = 0;
|
|
7147
|
+
while (removeCount < expiries.length && expiries[removeCount] <= now2) {
|
|
7148
|
+
removeCount++;
|
|
7149
|
+
}
|
|
7150
|
+
if (removeCount > 0) {
|
|
7151
|
+
expiries = expiries.slice(removeCount);
|
|
7152
|
+
let skipped = 0;
|
|
7153
|
+
decorations2 = decorations2.update({
|
|
7154
|
+
filter: () => {
|
|
7155
|
+
if (skipped < removeCount) {
|
|
7156
|
+
skipped++;
|
|
7157
|
+
return false;
|
|
7158
|
+
}
|
|
7159
|
+
return true;
|
|
7160
|
+
}
|
|
7161
|
+
});
|
|
7162
|
+
}
|
|
7163
|
+
}
|
|
7164
|
+
}
|
|
7165
|
+
if (!tr.docChanged) {
|
|
7166
|
+
log12(expiries);
|
|
7167
|
+
return {
|
|
7168
|
+
decorations: decorations2,
|
|
7169
|
+
expiries,
|
|
7170
|
+
batchStart
|
|
7171
|
+
};
|
|
7172
|
+
}
|
|
7173
|
+
let isReset = tr.state.doc.length === 0;
|
|
7174
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7175
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7176
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7177
|
+
isReset = true;
|
|
7178
|
+
}
|
|
7179
|
+
});
|
|
7180
|
+
}
|
|
7181
|
+
if (isReset) {
|
|
7182
|
+
log12([]);
|
|
7183
|
+
return {
|
|
7184
|
+
decorations: Decoration14.none,
|
|
7185
|
+
expiries: [],
|
|
7186
|
+
batchStart: 0
|
|
7187
|
+
};
|
|
7188
|
+
}
|
|
7189
|
+
const now = Date.now();
|
|
7190
|
+
const add = [];
|
|
7191
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
7192
|
+
if (toA === tr.startState.doc.length && inserted.length > 0) {
|
|
7193
|
+
add.push({
|
|
7194
|
+
from: fromB,
|
|
7195
|
+
to: toB
|
|
7196
|
+
});
|
|
7197
|
+
}
|
|
7198
|
+
});
|
|
7199
|
+
if (add.length > 0) {
|
|
7200
|
+
const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;
|
|
7201
|
+
if (canCoalesce) {
|
|
7202
|
+
let lastFrom = -1;
|
|
7203
|
+
let lastTo = -1;
|
|
7204
|
+
decorations2.between(0, tr.state.doc.length, (from, to) => {
|
|
7205
|
+
lastFrom = from;
|
|
7206
|
+
lastTo = to;
|
|
7207
|
+
});
|
|
7208
|
+
if (lastFrom >= 0) {
|
|
7209
|
+
decorations2 = decorations2.update({
|
|
7210
|
+
filter: (from, to) => !(from === lastFrom && to === lastTo)
|
|
7211
|
+
});
|
|
7212
|
+
const mergedFrom = Math.min(lastFrom, add[0].from);
|
|
7213
|
+
const mergedTo = add[add.length - 1].to;
|
|
7214
|
+
decorations2 = decorations2.update({
|
|
7215
|
+
add: [
|
|
7216
|
+
Decoration14.mark({
|
|
7217
|
+
class: "cm-fader"
|
|
7218
|
+
}).range(mergedFrom, mergedTo)
|
|
7219
|
+
]
|
|
7220
|
+
});
|
|
7221
|
+
expiries = [
|
|
7222
|
+
...expiries.slice(0, -1),
|
|
7223
|
+
now + removalDelay
|
|
7224
|
+
];
|
|
7225
|
+
}
|
|
7226
|
+
} else {
|
|
7227
|
+
batchStart = now;
|
|
7228
|
+
expiries = [
|
|
7229
|
+
...expiries,
|
|
7230
|
+
now + removalDelay
|
|
7231
|
+
];
|
|
7232
|
+
decorations2 = decorations2.update({
|
|
7233
|
+
add: add.map(({ from, to }) => Decoration14.mark({
|
|
7234
|
+
class: "cm-fader"
|
|
7235
|
+
}).range(from, to))
|
|
7236
|
+
});
|
|
7237
|
+
}
|
|
7238
|
+
}
|
|
7239
|
+
log12(expiries);
|
|
7240
|
+
return {
|
|
7241
|
+
decorations: decorations2,
|
|
7242
|
+
expiries,
|
|
7243
|
+
batchStart
|
|
7244
|
+
};
|
|
7245
|
+
},
|
|
7246
|
+
provide: (f) => EditorView29.decorations.from(f, (value) => value.decorations)
|
|
7247
|
+
});
|
|
7248
|
+
const cleanup = ViewPlugin20.fromClass(class {
|
|
7249
|
+
view;
|
|
7250
|
+
#timer;
|
|
7251
|
+
constructor(view) {
|
|
7252
|
+
this.view = view;
|
|
7253
|
+
this.#schedule();
|
|
7254
|
+
}
|
|
7255
|
+
update() {
|
|
7256
|
+
this.#schedule();
|
|
7257
|
+
}
|
|
7258
|
+
#schedule() {
|
|
7259
|
+
const { expiries } = this.view.state.field(fadeField);
|
|
7260
|
+
if (expiries.length === 0) {
|
|
7261
|
+
clearTimeout(this.#timer);
|
|
7262
|
+
this.#timer = void 0;
|
|
7263
|
+
return;
|
|
7264
|
+
}
|
|
7265
|
+
if (this.#timer !== void 0) {
|
|
7266
|
+
return;
|
|
7267
|
+
}
|
|
7268
|
+
const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());
|
|
7269
|
+
this.#timer = setTimeout(() => {
|
|
7270
|
+
this.#timer = void 0;
|
|
7271
|
+
this.view.dispatch({
|
|
7272
|
+
effects: dequeue.of(Date.now())
|
|
7273
|
+
});
|
|
7274
|
+
}, delay);
|
|
7275
|
+
}
|
|
7276
|
+
destroy() {
|
|
7277
|
+
clearTimeout(this.#timer);
|
|
7278
|
+
}
|
|
7279
|
+
});
|
|
7280
|
+
return [
|
|
7281
|
+
fadeField,
|
|
7282
|
+
cleanup,
|
|
7283
|
+
EditorView29.theme({
|
|
7284
|
+
".cm-fader": {
|
|
7285
|
+
animation: "fader 1s ease-out forwards"
|
|
7286
|
+
},
|
|
7287
|
+
"@keyframes fader": {
|
|
7288
|
+
"0%": {
|
|
7289
|
+
textShadow: "0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)"
|
|
7290
|
+
},
|
|
7291
|
+
"100%": {}
|
|
7292
|
+
}
|
|
7293
|
+
})
|
|
7294
|
+
];
|
|
7295
|
+
};
|
|
7296
|
+
|
|
7297
|
+
// src/extensions/tags/typewriter.ts
|
|
7298
|
+
import { Annotation as Annotation3, ChangeSet as ChangeSet2, EditorState as EditorState3, StateEffect as StateEffect11, StateField as StateField13 } from "@codemirror/state";
|
|
7299
|
+
import { Decoration as Decoration15, EditorView as EditorView30, ViewPlugin as ViewPlugin21, WidgetType as WidgetType9 } from "@codemirror/view";
|
|
7300
|
+
import { Domino as Domino3 } from "@dxos/ui";
|
|
7301
|
+
var typewriterBypass = Annotation3.define();
|
|
7302
|
+
var typewriterDrainingEffect = StateEffect11.define();
|
|
7303
|
+
var CURSOR_LINGER = 3e3;
|
|
7304
|
+
var FRAME_BUDGET_MS = 4;
|
|
7305
|
+
var CHARS_PER_FRAME = 5;
|
|
7306
|
+
var FLUSH_THRESHOLD = 2e3;
|
|
7307
|
+
var COMPACT_HEAD_THRESHOLD = 4096;
|
|
7308
|
+
var typewriter = (options = {}) => {
|
|
7309
|
+
const streamingTags = options.streamingTags ?? /* @__PURE__ */ new Set();
|
|
7310
|
+
const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;
|
|
7311
|
+
const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;
|
|
7312
|
+
const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;
|
|
7313
|
+
const suppressAppend = StateEffect11.define();
|
|
7314
|
+
const insertChunk = StateEffect11.define();
|
|
7315
|
+
const bufferField = StateField13.define({
|
|
7316
|
+
create: () => ({
|
|
7317
|
+
text: "",
|
|
7318
|
+
head: 0,
|
|
7319
|
+
insertAt: 0
|
|
7320
|
+
}),
|
|
7321
|
+
update: (value, tr) => {
|
|
7322
|
+
let { text, head, insertAt } = value;
|
|
7323
|
+
for (const effect of tr.effects) {
|
|
7324
|
+
if (effect.is(suppressAppend)) {
|
|
7325
|
+
if (text.length === head) {
|
|
7326
|
+
insertAt = effect.value.from;
|
|
7327
|
+
}
|
|
7328
|
+
text += effect.value.text;
|
|
7329
|
+
}
|
|
7330
|
+
if (effect.is(insertChunk)) {
|
|
7331
|
+
head += effect.value.text.length;
|
|
7332
|
+
insertAt = effect.value.from + effect.value.text.length;
|
|
7333
|
+
if (head >= COMPACT_HEAD_THRESHOLD || head > 0 && head * 2 >= text.length) {
|
|
7334
|
+
text = text.slice(head);
|
|
7335
|
+
head = 0;
|
|
7336
|
+
}
|
|
6978
7337
|
}
|
|
6979
7338
|
}
|
|
6980
7339
|
if (tr.docChanged) {
|
|
6981
|
-
|
|
7340
|
+
let isReset = tr.state.doc.length === 0;
|
|
7341
|
+
if (!isReset && tr.startState.doc.length > 0) {
|
|
7342
|
+
tr.changes.iterChanges((fromA, toA) => {
|
|
7343
|
+
if (fromA === 0 && toA === tr.startState.doc.length) {
|
|
7344
|
+
isReset = true;
|
|
7345
|
+
}
|
|
7346
|
+
});
|
|
7347
|
+
}
|
|
7348
|
+
if (isReset) {
|
|
7349
|
+
return {
|
|
7350
|
+
text: "",
|
|
7351
|
+
head: 0,
|
|
7352
|
+
insertAt: 0
|
|
7353
|
+
};
|
|
7354
|
+
}
|
|
7355
|
+
if (!tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7356
|
+
insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));
|
|
7357
|
+
}
|
|
6982
7358
|
}
|
|
6983
|
-
return
|
|
7359
|
+
return {
|
|
7360
|
+
text,
|
|
7361
|
+
head,
|
|
7362
|
+
insertAt
|
|
7363
|
+
};
|
|
6984
7364
|
}
|
|
6985
7365
|
});
|
|
6986
|
-
const
|
|
7366
|
+
const filter = EditorState3.transactionFilter.of((tr) => {
|
|
7367
|
+
if (!tr.docChanged) {
|
|
7368
|
+
return tr;
|
|
7369
|
+
}
|
|
7370
|
+
if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {
|
|
7371
|
+
return tr;
|
|
7372
|
+
}
|
|
7373
|
+
let appendedText = "";
|
|
7374
|
+
let appendFrom = -1;
|
|
7375
|
+
let isAppendOnly = true;
|
|
7376
|
+
tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {
|
|
7377
|
+
if (toA === tr.startState.doc.length && fromA === toA && inserted.length > 0) {
|
|
7378
|
+
appendedText += inserted.sliceString(0);
|
|
7379
|
+
if (appendFrom === -1) {
|
|
7380
|
+
appendFrom = fromA;
|
|
7381
|
+
}
|
|
7382
|
+
} else {
|
|
7383
|
+
isAppendOnly = false;
|
|
7384
|
+
}
|
|
7385
|
+
});
|
|
7386
|
+
if (!isAppendOnly || appendedText.length === 0) {
|
|
7387
|
+
return tr;
|
|
7388
|
+
}
|
|
7389
|
+
return {
|
|
7390
|
+
changes: ChangeSet2.empty(tr.startState.doc.length),
|
|
7391
|
+
effects: suppressAppend.of({
|
|
7392
|
+
from: appendFrom,
|
|
7393
|
+
text: appendedText
|
|
7394
|
+
})
|
|
7395
|
+
};
|
|
7396
|
+
});
|
|
7397
|
+
const drainPlugin = ViewPlugin21.fromClass(class {
|
|
6987
7398
|
view;
|
|
6988
|
-
|
|
7399
|
+
_raf;
|
|
7400
|
+
_activeStreamTag = null;
|
|
6989
7401
|
constructor(view) {
|
|
6990
7402
|
this.view = view;
|
|
6991
7403
|
}
|
|
6992
7404
|
update(update2) {
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7405
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7406
|
+
const pending = text.length - head;
|
|
7407
|
+
if (pending === 0) {
|
|
7408
|
+
this._activeStreamTag = null;
|
|
7409
|
+
}
|
|
7410
|
+
if (pending > 0 && this._raf === void 0) {
|
|
7411
|
+
this._start();
|
|
7000
7412
|
}
|
|
7001
7413
|
}
|
|
7414
|
+
_start() {
|
|
7415
|
+
queueMicrotask(() => {
|
|
7416
|
+
this.view.dispatch({
|
|
7417
|
+
effects: typewriterDrainingEffect.of(true),
|
|
7418
|
+
annotations: typewriterBypass.of(true)
|
|
7419
|
+
});
|
|
7420
|
+
});
|
|
7421
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7422
|
+
}
|
|
7423
|
+
_tick = () => {
|
|
7424
|
+
const { text, head, insertAt } = this.view.state.field(bufferField);
|
|
7425
|
+
const pending = text.length - head;
|
|
7426
|
+
if (pending === 0) {
|
|
7427
|
+
this.view.dispatch({
|
|
7428
|
+
effects: typewriterDrainingEffect.of(false),
|
|
7429
|
+
annotations: typewriterBypass.of(true)
|
|
7430
|
+
});
|
|
7431
|
+
this._raf = void 0;
|
|
7432
|
+
return;
|
|
7433
|
+
}
|
|
7434
|
+
if (pending > flushThreshold) {
|
|
7435
|
+
const chunk = text.slice(head);
|
|
7436
|
+
this._activeStreamTag = null;
|
|
7437
|
+
this.view.dispatch({
|
|
7438
|
+
changes: {
|
|
7439
|
+
from: insertAt,
|
|
7440
|
+
insert: chunk
|
|
7441
|
+
},
|
|
7442
|
+
effects: insertChunk.of({
|
|
7443
|
+
from: insertAt,
|
|
7444
|
+
text: chunk
|
|
7445
|
+
})
|
|
7446
|
+
});
|
|
7447
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7448
|
+
return;
|
|
7449
|
+
}
|
|
7450
|
+
const startTime = performance.now();
|
|
7451
|
+
let pos = head;
|
|
7452
|
+
let activeTag = this._activeStreamTag;
|
|
7453
|
+
let charsEmitted = 0;
|
|
7454
|
+
while (pos < text.length && performance.now() - startTime < frameBudgetMs) {
|
|
7455
|
+
const result = flushable(text, pos, streamingTags, activeTag);
|
|
7456
|
+
if (result.count === 0) {
|
|
7457
|
+
break;
|
|
7458
|
+
}
|
|
7459
|
+
if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {
|
|
7460
|
+
break;
|
|
7461
|
+
}
|
|
7462
|
+
if (result.enterTag) {
|
|
7463
|
+
activeTag = result.enterTag;
|
|
7464
|
+
}
|
|
7465
|
+
if (result.exitTag) {
|
|
7466
|
+
activeTag = null;
|
|
7467
|
+
}
|
|
7468
|
+
pos += result.count;
|
|
7469
|
+
charsEmitted += result.count;
|
|
7470
|
+
}
|
|
7471
|
+
const totalCount = pos - head;
|
|
7472
|
+
if (totalCount > 0) {
|
|
7473
|
+
const chunk = text.slice(head, head + totalCount);
|
|
7474
|
+
this._activeStreamTag = activeTag;
|
|
7475
|
+
this.view.dispatch({
|
|
7476
|
+
changes: {
|
|
7477
|
+
from: insertAt,
|
|
7478
|
+
insert: chunk
|
|
7479
|
+
},
|
|
7480
|
+
effects: insertChunk.of({
|
|
7481
|
+
from: insertAt,
|
|
7482
|
+
text: chunk
|
|
7483
|
+
})
|
|
7484
|
+
});
|
|
7485
|
+
}
|
|
7486
|
+
this._raf = requestAnimationFrame(this._tick);
|
|
7487
|
+
};
|
|
7002
7488
|
destroy() {
|
|
7003
|
-
|
|
7489
|
+
if (this._raf !== void 0) {
|
|
7490
|
+
cancelAnimationFrame(this._raf);
|
|
7491
|
+
}
|
|
7004
7492
|
}
|
|
7005
7493
|
});
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7494
|
+
return [
|
|
7495
|
+
bufferField,
|
|
7496
|
+
filter,
|
|
7497
|
+
drainPlugin,
|
|
7498
|
+
options.cursor && typewriterCursor(bufferField)
|
|
7499
|
+
].filter(Boolean);
|
|
7500
|
+
};
|
|
7501
|
+
var typewriterCursor = (bufferField) => {
|
|
7502
|
+
const hideCursor = StateEffect11.define();
|
|
7503
|
+
const visibilityField = StateField13.define({
|
|
7504
|
+
create: () => ({
|
|
7505
|
+
visible: false,
|
|
7506
|
+
insertAt: 0,
|
|
7507
|
+
lastNonWsAt: 0
|
|
7508
|
+
}),
|
|
7509
|
+
update: (value, tr) => {
|
|
7510
|
+
const { text, head, insertAt } = tr.state.field(bufferField);
|
|
7511
|
+
const pending = text.length - head;
|
|
7512
|
+
if (pending > 0) {
|
|
7513
|
+
let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));
|
|
7514
|
+
if (tr.docChanged) {
|
|
7515
|
+
tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
|
|
7516
|
+
const chunk = inserted.sliceString(0);
|
|
7517
|
+
if (chunk.trim().length > 0) {
|
|
7518
|
+
lastNonWsAt = _fromB + chunk.length;
|
|
7519
|
+
}
|
|
7520
|
+
});
|
|
7521
|
+
}
|
|
7522
|
+
return {
|
|
7523
|
+
visible: true,
|
|
7524
|
+
insertAt,
|
|
7525
|
+
lastNonWsAt
|
|
7526
|
+
};
|
|
7012
7527
|
}
|
|
7013
|
-
const
|
|
7014
|
-
|
|
7015
|
-
|
|
7528
|
+
for (const effect of tr.effects) {
|
|
7529
|
+
if (effect.is(hideCursor)) {
|
|
7530
|
+
return {
|
|
7531
|
+
...value,
|
|
7532
|
+
visible: false
|
|
7533
|
+
};
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
return value;
|
|
7537
|
+
}
|
|
7538
|
+
});
|
|
7539
|
+
const decorationField = StateField13.define({
|
|
7540
|
+
create: () => Decoration15.none,
|
|
7541
|
+
update: (_decorations, tr) => {
|
|
7542
|
+
const { visible, insertAt, lastNonWsAt } = tr.state.field(visibilityField);
|
|
7543
|
+
if (!visible) {
|
|
7544
|
+
return Decoration15.none;
|
|
7545
|
+
}
|
|
7546
|
+
const { text, head } = tr.state.field(bufferField);
|
|
7547
|
+
const cursorAt = text.length > head ? insertAt : lastNonWsAt;
|
|
7548
|
+
const pos = Math.min(cursorAt, tr.state.doc.length);
|
|
7549
|
+
return Decoration15.set([
|
|
7550
|
+
Decoration15.widget({
|
|
7016
7551
|
widget: new CursorWidget(),
|
|
7017
7552
|
side: 1
|
|
7018
|
-
}).range(
|
|
7553
|
+
}).range(pos)
|
|
7019
7554
|
]);
|
|
7020
7555
|
},
|
|
7021
|
-
provide: (
|
|
7556
|
+
provide: (field) => EditorView30.decorations.from(field)
|
|
7557
|
+
});
|
|
7558
|
+
const timerPlugin = ViewPlugin21.fromClass(class {
|
|
7559
|
+
view;
|
|
7560
|
+
_timer;
|
|
7561
|
+
constructor(view) {
|
|
7562
|
+
this.view = view;
|
|
7563
|
+
}
|
|
7564
|
+
update(update2) {
|
|
7565
|
+
const { text, head } = update2.state.field(bufferField);
|
|
7566
|
+
const { visible } = update2.state.field(visibilityField);
|
|
7567
|
+
const pending = text.length - head;
|
|
7568
|
+
if (pending > 0) {
|
|
7569
|
+
clearTimeout(this._timer);
|
|
7570
|
+
this._timer = void 0;
|
|
7571
|
+
} else if (visible && this._timer === void 0) {
|
|
7572
|
+
this._timer = setTimeout(() => {
|
|
7573
|
+
this.view.dispatch({
|
|
7574
|
+
effects: hideCursor.of(null)
|
|
7575
|
+
});
|
|
7576
|
+
this._timer = void 0;
|
|
7577
|
+
}, CURSOR_LINGER);
|
|
7578
|
+
}
|
|
7579
|
+
}
|
|
7580
|
+
destroy() {
|
|
7581
|
+
clearTimeout(this._timer);
|
|
7582
|
+
}
|
|
7022
7583
|
});
|
|
7023
7584
|
return [
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7585
|
+
visibilityField,
|
|
7586
|
+
decorationField,
|
|
7587
|
+
timerPlugin
|
|
7027
7588
|
];
|
|
7028
7589
|
};
|
|
7029
|
-
var CursorWidget = class extends WidgetType9 {
|
|
7590
|
+
var CursorWidget = class _CursorWidget extends WidgetType9 {
|
|
7591
|
+
// All instances are interchangeable — let CM reuse the existing DOM across drips so
|
|
7592
|
+
// the blink animation isn't restarted on every transaction.
|
|
7593
|
+
eq(other) {
|
|
7594
|
+
return other instanceof _CursorWidget;
|
|
7595
|
+
}
|
|
7030
7596
|
toDOM() {
|
|
7031
|
-
const inner = Domino3.of("span").text("\
|
|
7032
|
-
animation: "blink
|
|
7597
|
+
const inner = Domino3.of("span").text("\u2217").style({
|
|
7598
|
+
animation: "blink 1s infinite",
|
|
7599
|
+
animationDelay: "250ms"
|
|
7033
7600
|
});
|
|
7034
7601
|
return Domino3.of("span").style({
|
|
7035
7602
|
opacity: "0.8"
|
|
7036
|
-
}).
|
|
7603
|
+
}).append(inner).root;
|
|
7037
7604
|
}
|
|
7038
7605
|
};
|
|
7039
|
-
var
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7606
|
+
var OPENING_TAG_NAME = /^<([a-zA-Z][\w-]*)/;
|
|
7607
|
+
var TAG_NAME_PROBE = 64;
|
|
7608
|
+
var escapeRegExpSource2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7609
|
+
var flushable = (buffer, start, streamingTags, activeStreamTag) => {
|
|
7610
|
+
if (start >= buffer.length) {
|
|
7611
|
+
return {
|
|
7612
|
+
count: 0
|
|
7613
|
+
};
|
|
7614
|
+
}
|
|
7615
|
+
if (activeStreamTag) {
|
|
7616
|
+
const closeTag = `</${activeStreamTag}>`;
|
|
7617
|
+
if (buffer.startsWith(closeTag, start)) {
|
|
7618
|
+
return {
|
|
7619
|
+
count: closeTag.length,
|
|
7620
|
+
exitTag: true
|
|
7621
|
+
};
|
|
7622
|
+
}
|
|
7623
|
+
if (buffer[start] === "<") {
|
|
7624
|
+
return {
|
|
7625
|
+
count: xmlElementLength(buffer, start)
|
|
7626
|
+
};
|
|
7627
|
+
}
|
|
7628
|
+
return {
|
|
7629
|
+
count: 1
|
|
7630
|
+
};
|
|
7631
|
+
}
|
|
7632
|
+
const ch = buffer[start];
|
|
7633
|
+
if (ch === "<") {
|
|
7634
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7635
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7636
|
+
if (nameMatch && streamingTags.has(nameMatch[1])) {
|
|
7637
|
+
const close = buffer.indexOf(">", start);
|
|
7638
|
+
if (close === -1) {
|
|
7639
|
+
return {
|
|
7640
|
+
count: 0
|
|
7641
|
+
};
|
|
7058
7642
|
}
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
isReset = true;
|
|
7064
|
-
}
|
|
7065
|
-
});
|
|
7643
|
+
if (buffer[close - 1] === "/") {
|
|
7644
|
+
return {
|
|
7645
|
+
count: close + 1 - start
|
|
7646
|
+
};
|
|
7066
7647
|
}
|
|
7067
|
-
|
|
7068
|
-
|
|
7648
|
+
return {
|
|
7649
|
+
count: close + 1 - start,
|
|
7650
|
+
enterTag: nameMatch[1]
|
|
7651
|
+
};
|
|
7652
|
+
}
|
|
7653
|
+
return {
|
|
7654
|
+
count: xmlElementLength(buffer, start)
|
|
7655
|
+
};
|
|
7656
|
+
}
|
|
7657
|
+
if (ch === "!" && buffer.length > start + 1 && buffer[start + 1] === "[") {
|
|
7658
|
+
return {
|
|
7659
|
+
count: linkLength(buffer, start, start + 1)
|
|
7660
|
+
};
|
|
7661
|
+
}
|
|
7662
|
+
if (ch === "[") {
|
|
7663
|
+
return {
|
|
7664
|
+
count: linkLength(buffer, start, start)
|
|
7665
|
+
};
|
|
7666
|
+
}
|
|
7667
|
+
return {
|
|
7668
|
+
count: 1
|
|
7669
|
+
};
|
|
7670
|
+
};
|
|
7671
|
+
var xmlElementLength = (buffer, start = 0) => {
|
|
7672
|
+
const close = buffer.indexOf(">", start);
|
|
7673
|
+
if (close === -1) {
|
|
7674
|
+
return 0;
|
|
7675
|
+
}
|
|
7676
|
+
if (buffer[close - 1] === "/") {
|
|
7677
|
+
return close + 1 - start;
|
|
7678
|
+
}
|
|
7679
|
+
if (buffer[start + 1] === "/") {
|
|
7680
|
+
return close + 1 - start;
|
|
7681
|
+
}
|
|
7682
|
+
const probe = buffer.slice(start, start + TAG_NAME_PROBE);
|
|
7683
|
+
const nameMatch = probe.match(OPENING_TAG_NAME);
|
|
7684
|
+
if (!nameMatch) {
|
|
7685
|
+
return 1;
|
|
7686
|
+
}
|
|
7687
|
+
const tagName = nameMatch[1];
|
|
7688
|
+
let depth = 0;
|
|
7689
|
+
const tagPattern = new RegExp(`<(/?)${escapeRegExpSource2(tagName)}(\\s[^>]*)?>`, "g");
|
|
7690
|
+
tagPattern.lastIndex = start;
|
|
7691
|
+
let match;
|
|
7692
|
+
while ((match = tagPattern.exec(buffer)) !== null) {
|
|
7693
|
+
const isSelfClosing = match[0].endsWith("/>");
|
|
7694
|
+
const isClosing = match[1] === "/";
|
|
7695
|
+
if (isSelfClosing) {
|
|
7696
|
+
if (depth === 0) {
|
|
7697
|
+
return match.index + match[0].length - start;
|
|
7698
|
+
}
|
|
7699
|
+
} else if (isClosing) {
|
|
7700
|
+
depth--;
|
|
7701
|
+
if (depth === 0) {
|
|
7702
|
+
return match.index + match[0].length - start;
|
|
7069
7703
|
}
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7704
|
+
} else {
|
|
7705
|
+
depth++;
|
|
7706
|
+
}
|
|
7707
|
+
}
|
|
7708
|
+
return 0;
|
|
7709
|
+
};
|
|
7710
|
+
var linkLength = (buffer, start, bracketAt) => {
|
|
7711
|
+
const bracketClose = buffer.indexOf("]", bracketAt + 1);
|
|
7712
|
+
if (bracketClose === -1) {
|
|
7713
|
+
return 0;
|
|
7714
|
+
}
|
|
7715
|
+
if (bracketClose + 1 >= buffer.length) {
|
|
7716
|
+
return 0;
|
|
7717
|
+
}
|
|
7718
|
+
if (buffer[bracketClose + 1] !== "(") {
|
|
7719
|
+
return 1;
|
|
7720
|
+
}
|
|
7721
|
+
const parenClose = buffer.indexOf(")", bracketClose + 2);
|
|
7722
|
+
if (parenClose === -1) {
|
|
7723
|
+
return 0;
|
|
7724
|
+
}
|
|
7725
|
+
return parenClose + 1 - start;
|
|
7726
|
+
};
|
|
7727
|
+
|
|
7728
|
+
// src/extensions/tags/xml-block-decoration.ts
|
|
7729
|
+
import { xmlLanguage as xmlLanguage2 } from "@codemirror/lang-xml";
|
|
7730
|
+
import { Decoration as Decoration16, ViewPlugin as ViewPlugin22 } from "@codemirror/view";
|
|
7731
|
+
var xmlBlockDecoration = ({ tag, lineClass, contentClass, hideTags }) => {
|
|
7732
|
+
const lineDecoration = lineClass ? Decoration16.line({
|
|
7733
|
+
class: lineClass
|
|
7734
|
+
}) : void 0;
|
|
7735
|
+
const contentDecoration = contentClass ? Decoration16.mark({
|
|
7736
|
+
class: contentClass
|
|
7737
|
+
}) : void 0;
|
|
7738
|
+
const hideDecoration = hideTags ? Decoration16.replace({}) : void 0;
|
|
7739
|
+
const buildDecorations5 = (view) => {
|
|
7740
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7741
|
+
if (!text.includes(`<${tag}`)) {
|
|
7742
|
+
return Decoration16.none;
|
|
7743
|
+
}
|
|
7744
|
+
const tree = xmlLanguage2.parser.parse(text);
|
|
7745
|
+
const ranges = [];
|
|
7746
|
+
tree.iterate({
|
|
7747
|
+
enter: (node) => {
|
|
7748
|
+
if (node.type.name !== "Element") {
|
|
7073
7749
|
return;
|
|
7074
7750
|
}
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7751
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7752
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7753
|
+
const tagNameNode = openTag?.getChild("TagName");
|
|
7754
|
+
if (!openTag || !tagNameNode) {
|
|
7755
|
+
return;
|
|
7079
7756
|
}
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7757
|
+
if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {
|
|
7758
|
+
return;
|
|
7759
|
+
}
|
|
7760
|
+
const contentFrom = openTag.to;
|
|
7761
|
+
const contentTo = closeTag?.from ?? node.node.to;
|
|
7762
|
+
if (hideDecoration) {
|
|
7763
|
+
ranges.push(hideDecoration.range(openTag.from, openTag.to));
|
|
7764
|
+
if (closeTag) {
|
|
7765
|
+
ranges.push(hideDecoration.range(closeTag.from, closeTag.to));
|
|
7766
|
+
}
|
|
7767
|
+
}
|
|
7768
|
+
if (contentDecoration && contentFrom < contentTo) {
|
|
7769
|
+
ranges.push(contentDecoration.range(contentFrom, contentTo));
|
|
7770
|
+
}
|
|
7771
|
+
if (lineDecoration && contentFrom <= view.state.doc.length) {
|
|
7772
|
+
let pos = contentFrom;
|
|
7773
|
+
while (pos <= contentTo && pos <= view.state.doc.length) {
|
|
7774
|
+
const line = view.state.doc.lineAt(pos);
|
|
7775
|
+
ranges.push(lineDecoration.range(line.from));
|
|
7776
|
+
if (line.to >= contentTo) {
|
|
7777
|
+
break;
|
|
7778
|
+
}
|
|
7779
|
+
pos = line.to + 1;
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
7782
|
+
}
|
|
7783
|
+
});
|
|
7784
|
+
return Decoration16.set(ranges, true);
|
|
7785
|
+
};
|
|
7786
|
+
return ViewPlugin22.fromClass(class {
|
|
7787
|
+
decorations;
|
|
7091
7788
|
constructor(view) {
|
|
7092
|
-
this.
|
|
7789
|
+
this.decorations = buildDecorations5(view);
|
|
7093
7790
|
}
|
|
7094
7791
|
update(update2) {
|
|
7095
|
-
if (
|
|
7096
|
-
|
|
7792
|
+
if (update2.docChanged) {
|
|
7793
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7097
7794
|
}
|
|
7098
|
-
|
|
7099
|
-
|
|
7795
|
+
}
|
|
7796
|
+
}, {
|
|
7797
|
+
decorations: (instance) => instance.decorations
|
|
7798
|
+
});
|
|
7799
|
+
};
|
|
7800
|
+
|
|
7801
|
+
// src/extensions/tags/xml-formatting.ts
|
|
7802
|
+
import { xmlLanguage as xmlLanguage3 } from "@codemirror/lang-xml";
|
|
7803
|
+
import { Decoration as Decoration17, EditorView as EditorView31, ViewPlugin as ViewPlugin23 } from "@codemirror/view";
|
|
7804
|
+
var XML_TAG_NODES = /* @__PURE__ */ new Set([
|
|
7805
|
+
"OpenTag",
|
|
7806
|
+
"CloseTag",
|
|
7807
|
+
"SelfClosingTag",
|
|
7808
|
+
"MismatchedCloseTag"
|
|
7809
|
+
]);
|
|
7810
|
+
var xmlElementMark = Decoration17.mark({
|
|
7811
|
+
class: "cm-xml-element"
|
|
7812
|
+
});
|
|
7813
|
+
var xmlTagMark = Decoration17.mark({
|
|
7814
|
+
class: "cm-xml-tag"
|
|
7815
|
+
});
|
|
7816
|
+
var xmlContentMark = Decoration17.mark({
|
|
7817
|
+
class: "cm-xml-content"
|
|
7818
|
+
});
|
|
7819
|
+
var xmlFormatting = ({ skip } = {}) => {
|
|
7820
|
+
const skipSet = skip && skip.length > 0 ? new Set(skip) : void 0;
|
|
7821
|
+
const buildDecorations5 = (view) => {
|
|
7822
|
+
const text = view.state.sliceDoc(0, view.state.doc.length);
|
|
7823
|
+
if (!text.includes("<")) {
|
|
7824
|
+
return Decoration17.none;
|
|
7825
|
+
}
|
|
7826
|
+
const tagNameAt = (node) => text.slice(node.from, node.to);
|
|
7827
|
+
const tree = xmlLanguage3.parser.parse(text);
|
|
7828
|
+
const ranges = [];
|
|
7829
|
+
tree.iterate({
|
|
7830
|
+
enter: (node) => {
|
|
7831
|
+
const name = node.type.name;
|
|
7832
|
+
if (name === "SelfClosingTag" && node.from < node.to) {
|
|
7833
|
+
if (skipSet) {
|
|
7834
|
+
const tagNameNode = node.node.getChild("TagName");
|
|
7835
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7836
|
+
return false;
|
|
7837
|
+
}
|
|
7838
|
+
}
|
|
7839
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7840
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7100
7841
|
return;
|
|
7101
7842
|
}
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7843
|
+
if (XML_TAG_NODES.has(name) && node.from < node.to) {
|
|
7844
|
+
ranges.push(xmlTagMark.range(node.from, node.to));
|
|
7845
|
+
return;
|
|
7846
|
+
}
|
|
7847
|
+
if (name === "Element" && node.from < node.to) {
|
|
7848
|
+
const openTag = node.node.getChild("OpenTag");
|
|
7849
|
+
if (openTag && skipSet) {
|
|
7850
|
+
const tagNameNode = openTag.getChild("TagName");
|
|
7851
|
+
if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {
|
|
7852
|
+
return false;
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
const closeTag = node.node.getChild("CloseTag") ?? node.node.getChild("MismatchedCloseTag");
|
|
7856
|
+
ranges.push(xmlElementMark.range(node.from, node.to));
|
|
7857
|
+
if (openTag && closeTag && openTag.to < closeTag.from) {
|
|
7858
|
+
ranges.push(xmlContentMark.range(openTag.to, closeTag.from));
|
|
7859
|
+
}
|
|
7105
7860
|
}
|
|
7106
|
-
const totalDelay = FADE_IN_DURATION + removalDelay;
|
|
7107
|
-
const id = setTimeout(() => {
|
|
7108
|
-
this.view.dispatch({
|
|
7109
|
-
effects: removeDecoration.of({
|
|
7110
|
-
from: fromB,
|
|
7111
|
-
to: toB
|
|
7112
|
-
})
|
|
7113
|
-
});
|
|
7114
|
-
this._timers.delete(key);
|
|
7115
|
-
}, totalDelay);
|
|
7116
|
-
this._timers.set(key, id);
|
|
7117
|
-
});
|
|
7118
|
-
}
|
|
7119
|
-
destroy() {
|
|
7120
|
-
for (const id of this._timers.values()) {
|
|
7121
|
-
clearTimeout(id);
|
|
7122
7861
|
}
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
}
|
|
7862
|
+
});
|
|
7863
|
+
return Decoration17.set(ranges, true);
|
|
7864
|
+
};
|
|
7126
7865
|
return [
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
},
|
|
7136
|
-
"@keyframes fade-in": {
|
|
7137
|
-
"0%": {
|
|
7138
|
-
opacity: "0"
|
|
7139
|
-
},
|
|
7140
|
-
"80%": {
|
|
7141
|
-
opacity: "1"
|
|
7142
|
-
},
|
|
7143
|
-
"100%": {
|
|
7144
|
-
opacity: "0.8"
|
|
7866
|
+
ViewPlugin23.fromClass(class {
|
|
7867
|
+
decorations;
|
|
7868
|
+
constructor(view) {
|
|
7869
|
+
this.decorations = buildDecorations5(view);
|
|
7870
|
+
}
|
|
7871
|
+
update(update2) {
|
|
7872
|
+
if (update2.docChanged) {
|
|
7873
|
+
this.decorations = buildDecorations5(update2.view);
|
|
7145
7874
|
}
|
|
7146
7875
|
}
|
|
7876
|
+
}, {
|
|
7877
|
+
decorations: (instance) => instance.decorations
|
|
7878
|
+
}),
|
|
7879
|
+
EditorView31.baseTheme({
|
|
7880
|
+
".cm-xml-element": {
|
|
7881
|
+
backgroundColor: "var(--color-current-surface)",
|
|
7882
|
+
borderRadius: "0.25rem",
|
|
7883
|
+
padding: "0.25rem"
|
|
7884
|
+
},
|
|
7885
|
+
".cm-xml-tag": {
|
|
7886
|
+
color: "var(--color-blue-500)",
|
|
7887
|
+
fontFamily: "var(--font-mono)"
|
|
7888
|
+
},
|
|
7889
|
+
".cm-xml-content": {}
|
|
7147
7890
|
})
|
|
7148
7891
|
];
|
|
7149
7892
|
};
|
|
7150
7893
|
|
|
7151
7894
|
// src/extensions/tags/xml-tags.ts
|
|
7152
7895
|
import { syntaxTree as syntaxTree11 } from "@codemirror/language";
|
|
7153
|
-
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as
|
|
7154
|
-
import { Decoration as
|
|
7896
|
+
import { Prec as Prec7, RangeSetBuilder as RangeSetBuilder7, StateEffect as StateEffect12, StateField as StateField14 } from "@codemirror/state";
|
|
7897
|
+
import { Decoration as Decoration18, EditorView as EditorView32, ViewPlugin as ViewPlugin24, WidgetType as WidgetType10, keymap as keymap14 } from "@codemirror/view";
|
|
7155
7898
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
7156
7899
|
import { log as log11 } from "@dxos/log";
|
|
7900
|
+
import { Domino as Domino4 } from "@dxos/ui";
|
|
7157
7901
|
|
|
7158
7902
|
// src/extensions/tags/xml-util.ts
|
|
7159
7903
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
7160
7904
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-util.ts";
|
|
7161
7905
|
var nodeToJson = (state, node) => {
|
|
7162
|
-
invariant6(node.type.name === "Element", "Node is not an Element", {
|
|
7163
|
-
F: __dxlog_file16,
|
|
7164
|
-
L: 18,
|
|
7165
|
-
S: void 0,
|
|
7166
|
-
A: [
|
|
7167
|
-
"node.type.name === 'Element'",
|
|
7168
|
-
"'Node is not an Element'"
|
|
7169
|
-
]
|
|
7170
|
-
});
|
|
7906
|
+
invariant6(node.type.name === "Element", "Node is not an Element", { "~LogMeta": "~LogMeta", F: __dxlog_file16, L: 8, S: void 0, A: ["node.type.name === 'Element'", "'Node is not an Element'"] });
|
|
7171
7907
|
const openTag = node.node.getChild("OpenTag") || node.node.getChild("SelfClosingTag");
|
|
7172
7908
|
if (openTag) {
|
|
7173
7909
|
const tagName = openTag.getChild("TagName");
|
|
@@ -7199,13 +7935,23 @@ var nodeToJson = (state, node) => {
|
|
|
7199
7935
|
if (node.type.name === "Element" && openTag.type.name !== "SelfClosingTag") {
|
|
7200
7936
|
const children = [];
|
|
7201
7937
|
let child = node.node.firstChild;
|
|
7938
|
+
const appendText = (raw) => {
|
|
7939
|
+
if (raw.length === 0) {
|
|
7940
|
+
return;
|
|
7941
|
+
}
|
|
7942
|
+
const last = children[children.length - 1];
|
|
7943
|
+
if (typeof last === "string") {
|
|
7944
|
+
children[children.length - 1] = last + raw;
|
|
7945
|
+
} else {
|
|
7946
|
+
children.push(raw);
|
|
7947
|
+
}
|
|
7948
|
+
};
|
|
7202
7949
|
while (child) {
|
|
7203
7950
|
if (child.type.name !== "OpenTag" && child.type.name !== "CloseTag") {
|
|
7204
7951
|
if (child.type.name === "Text") {
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
}
|
|
7952
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
7953
|
+
} else if (child.type.name === "EntityReference" || child.type.name === "CharacterReference") {
|
|
7954
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
7209
7955
|
} else if (child.type.name === "Element") {
|
|
7210
7956
|
const data = nodeToJson(state, child);
|
|
7211
7957
|
if (data) {
|
|
@@ -7215,26 +7961,63 @@ var nodeToJson = (state, node) => {
|
|
|
7215
7961
|
}
|
|
7216
7962
|
child = child.nextSibling;
|
|
7217
7963
|
}
|
|
7964
|
+
if (children.length > 0 && typeof children[0] === "string") {
|
|
7965
|
+
children[0] = children[0].trimStart();
|
|
7966
|
+
}
|
|
7218
7967
|
if (children.length > 0) {
|
|
7219
|
-
|
|
7968
|
+
const lastIndex = children.length - 1;
|
|
7969
|
+
const last = children[lastIndex];
|
|
7970
|
+
if (typeof last === "string") {
|
|
7971
|
+
children[lastIndex] = last.trimEnd();
|
|
7972
|
+
}
|
|
7973
|
+
}
|
|
7974
|
+
const trimmed = children.filter((value) => typeof value !== "string" || value.length > 0);
|
|
7975
|
+
if (trimmed.length > 0) {
|
|
7976
|
+
tag.children = trimmed;
|
|
7220
7977
|
}
|
|
7221
7978
|
}
|
|
7222
7979
|
return tag;
|
|
7223
7980
|
}
|
|
7224
7981
|
};
|
|
7982
|
+
var XML_NAMED_ENTITIES = {
|
|
7983
|
+
"<": "<",
|
|
7984
|
+
">": ">",
|
|
7985
|
+
"&": "&",
|
|
7986
|
+
""": '"',
|
|
7987
|
+
"'": "'"
|
|
7988
|
+
};
|
|
7989
|
+
var decodeXmlEntity = (raw) => {
|
|
7990
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
7991
|
+
if (named !== void 0) {
|
|
7992
|
+
return named;
|
|
7993
|
+
}
|
|
7994
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
7995
|
+
if (numeric) {
|
|
7996
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
7997
|
+
if (Number.isFinite(code)) {
|
|
7998
|
+
try {
|
|
7999
|
+
return String.fromCodePoint(code);
|
|
8000
|
+
} catch {
|
|
8001
|
+
}
|
|
8002
|
+
}
|
|
8003
|
+
}
|
|
8004
|
+
return raw;
|
|
8005
|
+
};
|
|
7225
8006
|
|
|
7226
8007
|
// src/extensions/tags/xml-tags.ts
|
|
7227
8008
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/tags/xml-tags.ts";
|
|
7228
|
-
var navigatePreviousEffect =
|
|
7229
|
-
var navigateNextEffect =
|
|
8009
|
+
var navigatePreviousEffect = StateEffect12.define();
|
|
8010
|
+
var navigateNextEffect = StateEffect12.define();
|
|
7230
8011
|
var getXmlTextChild = (children) => {
|
|
7231
8012
|
const child = children?.[0];
|
|
7232
8013
|
return typeof child === "string" ? child : null;
|
|
7233
8014
|
};
|
|
7234
|
-
var
|
|
7235
|
-
var
|
|
7236
|
-
var
|
|
7237
|
-
var
|
|
8015
|
+
var xmlWidgetId = (explicit, fallback) => typeof explicit === "string" && explicit.length > 0 ? explicit : fallback;
|
|
8016
|
+
var escapeRegExpSource3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8017
|
+
var xmlTagContextEffect = StateEffect12.define();
|
|
8018
|
+
var xmlTagResetEffect = StateEffect12.define();
|
|
8019
|
+
var xmlTagUpdateEffect = StateEffect12.define();
|
|
8020
|
+
var widgetContextStateField = StateField14.define({
|
|
7238
8021
|
create: () => void 0,
|
|
7239
8022
|
update: (value, tr) => {
|
|
7240
8023
|
for (const effect of tr.effects) {
|
|
@@ -7245,7 +8028,7 @@ var widgetContextStateField = StateField13.define({
|
|
|
7245
8028
|
return value;
|
|
7246
8029
|
}
|
|
7247
8030
|
});
|
|
7248
|
-
var widgetStateMapStateField =
|
|
8031
|
+
var widgetStateMapStateField = StateField14.define({
|
|
7249
8032
|
create: () => ({}),
|
|
7250
8033
|
update: (map, tr) => {
|
|
7251
8034
|
for (const effect of tr.effects) {
|
|
@@ -7257,12 +8040,7 @@ var widgetStateMapStateField = StateField13.define({
|
|
|
7257
8040
|
log11("widget updated", {
|
|
7258
8041
|
id,
|
|
7259
8042
|
value
|
|
7260
|
-
}, {
|
|
7261
|
-
F: __dxlog_file17,
|
|
7262
|
-
L: 153,
|
|
7263
|
-
S: void 0,
|
|
7264
|
-
C: (f, a) => f(...a)
|
|
7265
|
-
});
|
|
8043
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 59, S: void 0 });
|
|
7266
8044
|
const state = typeof value === "function" ? value(map[id]) : value;
|
|
7267
8045
|
return {
|
|
7268
8046
|
...map,
|
|
@@ -7292,12 +8070,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7292
8070
|
log11("widget mounted", {
|
|
7293
8071
|
id: state.id,
|
|
7294
8072
|
tag: state.props._tag
|
|
7295
|
-
}, {
|
|
7296
|
-
F: __dxlog_file17,
|
|
7297
|
-
L: 206,
|
|
7298
|
-
S: void 0,
|
|
7299
|
-
C: (f, a) => f(...a)
|
|
7300
|
-
});
|
|
8073
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 101, S: void 0 });
|
|
7301
8074
|
widgets.set(state.id, state);
|
|
7302
8075
|
setWidgets?.([
|
|
7303
8076
|
...widgets.values()
|
|
@@ -7308,12 +8081,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7308
8081
|
log11("widget unmounted", {
|
|
7309
8082
|
id,
|
|
7310
8083
|
tag: state?.props._tag
|
|
7311
|
-
}, {
|
|
7312
|
-
F: __dxlog_file17,
|
|
7313
|
-
L: 212,
|
|
7314
|
-
S: void 0,
|
|
7315
|
-
C: (f, a) => f(...a)
|
|
7316
|
-
});
|
|
8084
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 112, S: void 0 });
|
|
7317
8085
|
widgets.delete(id);
|
|
7318
8086
|
setWidgets?.([
|
|
7319
8087
|
...widgets.values()
|
|
@@ -7322,7 +8090,7 @@ var createWidgetMap = (setWidgets) => {
|
|
|
7322
8090
|
};
|
|
7323
8091
|
return notifier;
|
|
7324
8092
|
};
|
|
7325
|
-
var keyHandlers =
|
|
8093
|
+
var keyHandlers = keymap14.of([
|
|
7326
8094
|
{
|
|
7327
8095
|
key: "Mod-ArrowUp",
|
|
7328
8096
|
run: (view) => {
|
|
@@ -7343,7 +8111,7 @@ var keyHandlers = keymap13.of([
|
|
|
7343
8111
|
}
|
|
7344
8112
|
]);
|
|
7345
8113
|
var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
7346
|
-
return
|
|
8114
|
+
return EditorView32.updateListener.of((update2) => {
|
|
7347
8115
|
update2.transactions.forEach((transaction) => {
|
|
7348
8116
|
for (const effect of transaction.effects) {
|
|
7349
8117
|
if (effect.is(navigatePreviousEffect)) {
|
|
@@ -7428,7 +8196,7 @@ var createNavigationEffectPlugin = (widgetDecorationsField, bookmarks2) => {
|
|
|
7428
8196
|
});
|
|
7429
8197
|
});
|
|
7430
8198
|
};
|
|
7431
|
-
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) =>
|
|
8199
|
+
var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin24.fromClass(class {
|
|
7432
8200
|
update(update2) {
|
|
7433
8201
|
const widgetStateMap = update2.state.field(widgetStateMapStateField);
|
|
7434
8202
|
const { decorations: decorations2 } = update2.state.field(widgetDecorationsField);
|
|
@@ -7455,14 +8223,14 @@ var createWidgetUpdatePlugin = (widgetDecorationsField, notifier) => ViewPlugin1
|
|
|
7455
8223
|
}
|
|
7456
8224
|
}
|
|
7457
8225
|
});
|
|
7458
|
-
var createWidgetDecorationsField = (registry = {}, notifier) =>
|
|
8226
|
+
var createWidgetDecorationsField = (registry = {}, notifier) => StateField14.define({
|
|
7459
8227
|
create: (state) => {
|
|
7460
8228
|
return buildDecorations4(state, {
|
|
7461
8229
|
from: 0,
|
|
7462
8230
|
to: state.doc.length
|
|
7463
8231
|
}, registry, notifier);
|
|
7464
8232
|
},
|
|
7465
|
-
update: ({ from, decorations: decorations2 }, tr) => {
|
|
8233
|
+
update: ({ from, streamingFrom, decorations: decorations2 }, tr) => {
|
|
7466
8234
|
for (const effect of tr.effects) {
|
|
7467
8235
|
if (effect.is(xmlTagResetEffect)) {
|
|
7468
8236
|
if (tr.docChanged) {
|
|
@@ -7473,7 +8241,7 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7473
8241
|
}
|
|
7474
8242
|
return {
|
|
7475
8243
|
from: 0,
|
|
7476
|
-
decorations:
|
|
8244
|
+
decorations: Decoration18.none
|
|
7477
8245
|
};
|
|
7478
8246
|
}
|
|
7479
8247
|
}
|
|
@@ -7484,24 +8252,23 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7484
8252
|
log11("document reset", {
|
|
7485
8253
|
from,
|
|
7486
8254
|
to: state.doc.length
|
|
7487
|
-
}, {
|
|
7488
|
-
F: __dxlog_file17,
|
|
7489
|
-
L: 374,
|
|
7490
|
-
S: void 0,
|
|
7491
|
-
C: (f, a) => f(...a)
|
|
7492
|
-
});
|
|
8255
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 298, S: void 0 });
|
|
7493
8256
|
return buildDecorations4(state, {
|
|
7494
8257
|
from: 0,
|
|
7495
8258
|
to: state.doc.length
|
|
7496
8259
|
}, registry, notifier);
|
|
7497
8260
|
} else {
|
|
8261
|
+
const rebuildFrom = streamingFrom ?? from;
|
|
7498
8262
|
const result = buildDecorations4(state, {
|
|
7499
|
-
from,
|
|
8263
|
+
from: rebuildFrom,
|
|
7500
8264
|
to: state.doc.length
|
|
7501
8265
|
}, registry, notifier);
|
|
7502
8266
|
return {
|
|
7503
8267
|
from: result.from,
|
|
8268
|
+
streamingFrom: result.streamingFrom,
|
|
7504
8269
|
decorations: decorations2.update({
|
|
8270
|
+
// Remove old streaming decorations — they are rebuilt each tick.
|
|
8271
|
+
filter: (_f, _t, deco) => !deco.spec.streaming,
|
|
7505
8272
|
add: decorationSetToArray(result.decorations)
|
|
7506
8273
|
})
|
|
7507
8274
|
};
|
|
@@ -7509,12 +8276,13 @@ var createWidgetDecorationsField = (registry = {}, notifier) => StateField13.def
|
|
|
7509
8276
|
}
|
|
7510
8277
|
return {
|
|
7511
8278
|
from,
|
|
8279
|
+
streamingFrom,
|
|
7512
8280
|
decorations: decorations2
|
|
7513
8281
|
};
|
|
7514
8282
|
},
|
|
7515
8283
|
provide: (field) => [
|
|
7516
|
-
|
|
7517
|
-
|
|
8284
|
+
EditorView32.decorations.from(field, (v) => v.decorations),
|
|
8285
|
+
EditorView32.atomicRanges.of((view) => view.state.field(field).decorations || Decoration18.none)
|
|
7518
8286
|
]
|
|
7519
8287
|
});
|
|
7520
8288
|
var buildDecorations4 = (state, range, registry, notifier) => {
|
|
@@ -7525,10 +8293,11 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7525
8293
|
if (!tree || tree.type.name === "Program" && tree.length === 0) {
|
|
7526
8294
|
return {
|
|
7527
8295
|
from: range.from,
|
|
7528
|
-
decorations:
|
|
8296
|
+
decorations: Decoration18.none
|
|
7529
8297
|
};
|
|
7530
8298
|
}
|
|
7531
8299
|
let last = range.from;
|
|
8300
|
+
let streamingFrom;
|
|
7532
8301
|
tree.iterate({
|
|
7533
8302
|
from: range.from,
|
|
7534
8303
|
to: range.to,
|
|
@@ -7541,21 +8310,26 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7541
8310
|
if (args) {
|
|
7542
8311
|
const def = registry[args._tag];
|
|
7543
8312
|
if (def) {
|
|
8313
|
+
if (def.streaming && !node.node.getChild("CloseTag")) {
|
|
8314
|
+
return false;
|
|
8315
|
+
}
|
|
7544
8316
|
const { block, factory, Component } = def;
|
|
7545
|
-
const widgetState = args.id ? widgetStateMap[args.id] : void 0;
|
|
7546
8317
|
const nodeRange = {
|
|
7547
8318
|
from: node.node.from,
|
|
7548
8319
|
to: node.node.to
|
|
7549
8320
|
};
|
|
8321
|
+
const widgetId = xmlWidgetId(args.id, def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`);
|
|
8322
|
+
const widgetState = widgetStateMap[widgetId];
|
|
7550
8323
|
const props = {
|
|
7551
|
-
|
|
8324
|
+
id: widgetId,
|
|
7552
8325
|
range: nodeRange,
|
|
8326
|
+
context,
|
|
7553
8327
|
...args,
|
|
7554
8328
|
...widgetState
|
|
7555
8329
|
};
|
|
7556
|
-
const widget = factory ? factory(props) : Component ?
|
|
8330
|
+
const widget = factory ? factory(props) ?? void 0 : Component ? new PlaceholderWidget2(widgetId, Component, props, notifier) : void 0;
|
|
7557
8331
|
if (widget) {
|
|
7558
|
-
builder.add(nodeRange.from, nodeRange.to,
|
|
8332
|
+
builder.add(nodeRange.from, nodeRange.to, Decoration18.replace({
|
|
7559
8333
|
widget,
|
|
7560
8334
|
block,
|
|
7561
8335
|
atomic: true,
|
|
@@ -7567,20 +8341,72 @@ var buildDecorations4 = (state, range, registry, notifier) => {
|
|
|
7567
8341
|
}
|
|
7568
8342
|
}
|
|
7569
8343
|
} catch (err) {
|
|
7570
|
-
log11.catch(err, void 0, {
|
|
7571
|
-
F: __dxlog_file17,
|
|
7572
|
-
L: 459,
|
|
7573
|
-
S: void 0,
|
|
7574
|
-
C: (f, a) => f(...a)
|
|
7575
|
-
});
|
|
8344
|
+
log11.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 401, S: void 0 });
|
|
7576
8345
|
}
|
|
7577
8346
|
return false;
|
|
7578
8347
|
}
|
|
7579
8348
|
}
|
|
7580
8349
|
}
|
|
7581
8350
|
});
|
|
8351
|
+
const streamingTagNames = Object.entries(registry).filter(([, def]) => def.streaming).map(([name]) => name).sort((a, b) => b.length - a.length);
|
|
8352
|
+
if (streamingTagNames.length > 0) {
|
|
8353
|
+
const tailText = state.sliceDoc(range.from, range.to);
|
|
8354
|
+
const streamingPattern = streamingTagNames.map(escapeRegExpSource3).join("|");
|
|
8355
|
+
const tagPattern = new RegExp(`<(${streamingPattern})(\\s[^>]*)?>`, "g");
|
|
8356
|
+
let match;
|
|
8357
|
+
while ((match = tagPattern.exec(tailText)) !== null) {
|
|
8358
|
+
const tagName = match[1];
|
|
8359
|
+
const closeTag = `</${tagName}>`;
|
|
8360
|
+
const afterOpen = match.index + match[0].length;
|
|
8361
|
+
if (tailText.indexOf(closeTag, afterOpen) === -1) {
|
|
8362
|
+
const absoluteFrom = range.from + match.index;
|
|
8363
|
+
const contentFrom = range.from + afterOpen;
|
|
8364
|
+
const innerText = state.sliceDoc(contentFrom, range.to).trim();
|
|
8365
|
+
const def = registry[tagName];
|
|
8366
|
+
const props = {
|
|
8367
|
+
_tag: tagName,
|
|
8368
|
+
context,
|
|
8369
|
+
range: {
|
|
8370
|
+
from: absoluteFrom,
|
|
8371
|
+
to: range.to
|
|
8372
|
+
},
|
|
8373
|
+
children: innerText ? [
|
|
8374
|
+
innerText
|
|
8375
|
+
] : void 0
|
|
8376
|
+
};
|
|
8377
|
+
const attrPattern = /(\w+)="([^"]*)"/g;
|
|
8378
|
+
let attrMatch;
|
|
8379
|
+
while ((attrMatch = attrPattern.exec(match[0])) !== null) {
|
|
8380
|
+
props[attrMatch[1]] = attrMatch[2];
|
|
8381
|
+
}
|
|
8382
|
+
const widgetId = xmlWidgetId(props.id, `cm-xml-${absoluteFrom}`);
|
|
8383
|
+
const widgetState = widgetStateMap[widgetId];
|
|
8384
|
+
const mergedProps = {
|
|
8385
|
+
...props,
|
|
8386
|
+
id: widgetId,
|
|
8387
|
+
...widgetState
|
|
8388
|
+
};
|
|
8389
|
+
const widget = def.factory ? def.factory(mergedProps) ?? void 0 : def.Component ? new PlaceholderWidget2(widgetId, def.Component, mergedProps, notifier, true) : void 0;
|
|
8390
|
+
if (widget) {
|
|
8391
|
+
builder.add(absoluteFrom, range.to, Decoration18.replace({
|
|
8392
|
+
widget,
|
|
8393
|
+
block: def.block,
|
|
8394
|
+
atomic: true,
|
|
8395
|
+
inclusive: true,
|
|
8396
|
+
tag: tagName,
|
|
8397
|
+
streaming: true,
|
|
8398
|
+
contentFrom
|
|
8399
|
+
}));
|
|
8400
|
+
streamingFrom = absoluteFrom;
|
|
8401
|
+
last = absoluteFrom;
|
|
8402
|
+
}
|
|
8403
|
+
break;
|
|
8404
|
+
}
|
|
8405
|
+
}
|
|
8406
|
+
}
|
|
7582
8407
|
return {
|
|
7583
8408
|
from: last,
|
|
8409
|
+
streamingFrom,
|
|
7584
8410
|
decorations: builder.finish()
|
|
7585
8411
|
};
|
|
7586
8412
|
};
|
|
@@ -7589,108 +8415,62 @@ var PlaceholderWidget2 = class extends WidgetType10 {
|
|
|
7589
8415
|
Component;
|
|
7590
8416
|
props;
|
|
7591
8417
|
notifier;
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
S: this,
|
|
7599
|
-
A: [
|
|
7600
|
-
"id",
|
|
7601
|
-
""
|
|
7602
|
-
]
|
|
7603
|
-
});
|
|
8418
|
+
streaming;
|
|
8419
|
+
#root = null;
|
|
8420
|
+
#view;
|
|
8421
|
+
constructor(id, Component, props, notifier, streaming) {
|
|
8422
|
+
super(), this.id = id, this.Component = Component, this.props = props, this.notifier = notifier, this.streaming = streaming;
|
|
8423
|
+
invariant7(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file17, L: 488, S: this, A: ["id", ""] });
|
|
7604
8424
|
}
|
|
7605
8425
|
get root() {
|
|
7606
|
-
return this
|
|
8426
|
+
return this.#root;
|
|
7607
8427
|
}
|
|
7608
8428
|
eq(other) {
|
|
8429
|
+
if (this.streaming) {
|
|
8430
|
+
return false;
|
|
8431
|
+
}
|
|
7609
8432
|
return this.id === other.id;
|
|
7610
8433
|
}
|
|
7611
8434
|
ignoreEvent() {
|
|
7612
8435
|
return true;
|
|
7613
8436
|
}
|
|
7614
|
-
toDOM(
|
|
7615
|
-
this
|
|
8437
|
+
toDOM(view) {
|
|
8438
|
+
this.#view = view;
|
|
8439
|
+
this.#root = Domino4.of("div").classNames("min-h-[24px]").root;
|
|
8440
|
+
const props = Object.assign({}, this.props, {
|
|
8441
|
+
view
|
|
8442
|
+
});
|
|
8443
|
+
this.notifier.mounted({
|
|
8444
|
+
id: this.id,
|
|
8445
|
+
root: this.#root,
|
|
8446
|
+
props,
|
|
8447
|
+
Component: this.Component
|
|
8448
|
+
});
|
|
8449
|
+
return this.#root;
|
|
8450
|
+
}
|
|
8451
|
+
updateDOM(dom) {
|
|
8452
|
+
this.#root = dom;
|
|
8453
|
+
const props = Object.assign({}, this.props, {
|
|
8454
|
+
view: this.#view
|
|
8455
|
+
});
|
|
7616
8456
|
this.notifier.mounted({
|
|
7617
8457
|
id: this.id,
|
|
7618
|
-
root: this
|
|
7619
|
-
props
|
|
8458
|
+
root: this.#root,
|
|
8459
|
+
props,
|
|
7620
8460
|
Component: this.Component
|
|
7621
8461
|
});
|
|
7622
|
-
return
|
|
8462
|
+
return true;
|
|
7623
8463
|
}
|
|
7624
8464
|
destroy(_dom) {
|
|
7625
8465
|
this.notifier.unmounted(this.id);
|
|
7626
|
-
this
|
|
8466
|
+
this.#root = null;
|
|
8467
|
+
this.#view = void 0;
|
|
7627
8468
|
}
|
|
7628
8469
|
};
|
|
7629
|
-
|
|
7630
|
-
// src/extensions/typewriter.ts
|
|
7631
|
-
import { keymap as keymap14 } from "@codemirror/view";
|
|
7632
|
-
var defaultItems = [
|
|
7633
|
-
"hello world!",
|
|
7634
|
-
"this is a test.",
|
|
7635
|
-
"this is [DXOS](https://dxos.org)"
|
|
7636
|
-
];
|
|
7637
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
7638
|
-
let t;
|
|
7639
|
-
let idx = 0;
|
|
7640
|
-
return [
|
|
7641
|
-
keymap14.of([
|
|
7642
|
-
{
|
|
7643
|
-
// Reset.
|
|
7644
|
-
key: "alt-meta-'",
|
|
7645
|
-
run: () => {
|
|
7646
|
-
clearTimeout(t);
|
|
7647
|
-
idx = 0;
|
|
7648
|
-
return true;
|
|
7649
|
-
}
|
|
7650
|
-
},
|
|
7651
|
-
{
|
|
7652
|
-
// Next prompt.
|
|
7653
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
|
7654
|
-
key: "Shift-Meta-'",
|
|
7655
|
-
run: (view) => {
|
|
7656
|
-
clearTimeout(t);
|
|
7657
|
-
const text = items[idx++];
|
|
7658
|
-
if (idx === items?.length) {
|
|
7659
|
-
idx = 0;
|
|
7660
|
-
}
|
|
7661
|
-
let i = 0;
|
|
7662
|
-
const insert = (d = 0) => {
|
|
7663
|
-
t = setTimeout(() => {
|
|
7664
|
-
const pos = view.state.selection.main.head;
|
|
7665
|
-
view.dispatch({
|
|
7666
|
-
changes: {
|
|
7667
|
-
from: pos,
|
|
7668
|
-
insert: text[i++]
|
|
7669
|
-
},
|
|
7670
|
-
selection: {
|
|
7671
|
-
anchor: pos + 1
|
|
7672
|
-
}
|
|
7673
|
-
});
|
|
7674
|
-
if (i < text.length) {
|
|
7675
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
|
7676
|
-
}
|
|
7677
|
-
}, d);
|
|
7678
|
-
};
|
|
7679
|
-
insert();
|
|
7680
|
-
return true;
|
|
7681
|
-
}
|
|
7682
|
-
}
|
|
7683
|
-
])
|
|
7684
|
-
];
|
|
7685
|
-
};
|
|
7686
8470
|
export {
|
|
7687
8471
|
Cursor,
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
EditorState3 as EditorState,
|
|
7691
|
-
EditorView30 as EditorView,
|
|
7692
|
-
EditorViewMode,
|
|
7693
|
-
EditorViewModes,
|
|
8472
|
+
EditorState4 as EditorState,
|
|
8473
|
+
EditorView33 as EditorView,
|
|
7694
8474
|
Inline,
|
|
7695
8475
|
InputModeExtensions,
|
|
7696
8476
|
List,
|
|
@@ -7707,6 +8487,7 @@ export {
|
|
|
7707
8487
|
addStyle,
|
|
7708
8488
|
annotations,
|
|
7709
8489
|
autoScroll,
|
|
8490
|
+
autoScrollEffect,
|
|
7710
8491
|
autocomplete,
|
|
7711
8492
|
automerge,
|
|
7712
8493
|
awareness,
|
|
@@ -7720,6 +8501,7 @@ export {
|
|
|
7720
8501
|
commentClickedEffect,
|
|
7721
8502
|
comments,
|
|
7722
8503
|
commentsState,
|
|
8504
|
+
compactSlots,
|
|
7723
8505
|
convertTreeToJson,
|
|
7724
8506
|
createBasicExtensions,
|
|
7725
8507
|
createComment,
|
|
@@ -7743,12 +8525,12 @@ export {
|
|
|
7743
8525
|
defaultThemeSlots,
|
|
7744
8526
|
deleteItem,
|
|
7745
8527
|
documentId,
|
|
8528
|
+
documentSlots,
|
|
7746
8529
|
dropFile,
|
|
8530
|
+
editorClassNames,
|
|
7747
8531
|
editorInputMode,
|
|
7748
|
-
editorSlots,
|
|
7749
|
-
editorWidth,
|
|
7750
|
-
editorWithToolbarLayout,
|
|
7751
8532
|
extendedMarkdown,
|
|
8533
|
+
fader,
|
|
7752
8534
|
filterChars,
|
|
7753
8535
|
flattenRect,
|
|
7754
8536
|
focus,
|
|
@@ -7784,6 +8566,7 @@ export {
|
|
|
7784
8566
|
markdownTagsExtensions,
|
|
7785
8567
|
matchCompletion,
|
|
7786
8568
|
mention,
|
|
8569
|
+
mobileSlots,
|
|
7787
8570
|
modalStateEffect,
|
|
7788
8571
|
modalStateField,
|
|
7789
8572
|
moveItemDown,
|
|
@@ -7803,6 +8586,7 @@ export {
|
|
|
7803
8586
|
removeList,
|
|
7804
8587
|
removeStyle,
|
|
7805
8588
|
replacer,
|
|
8589
|
+
scrollPastEnd,
|
|
7806
8590
|
scrollThreadIntoView,
|
|
7807
8591
|
scrollToLine,
|
|
7808
8592
|
scroller,
|
|
@@ -7815,9 +8599,8 @@ export {
|
|
|
7815
8599
|
setSelection,
|
|
7816
8600
|
setStyle,
|
|
7817
8601
|
singleValueFacet,
|
|
7818
|
-
|
|
8602
|
+
snippets2 as snippets,
|
|
7819
8603
|
staticCompletion,
|
|
7820
|
-
streamer,
|
|
7821
8604
|
submit,
|
|
7822
8605
|
tabbable,
|
|
7823
8606
|
table,
|
|
@@ -7836,7 +8619,12 @@ export {
|
|
|
7836
8619
|
treeFacet,
|
|
7837
8620
|
typeahead,
|
|
7838
8621
|
typewriter,
|
|
8622
|
+
typewriterBypass,
|
|
8623
|
+
typewriterDrainingEffect,
|
|
7839
8624
|
wrapWithCatch,
|
|
8625
|
+
xmlBlockDecoration,
|
|
8626
|
+
xmlElementLength,
|
|
8627
|
+
xmlFormatting,
|
|
7840
8628
|
xmlTagContextEffect,
|
|
7841
8629
|
xmlTagResetEffect,
|
|
7842
8630
|
xmlTagUpdateEffect,
|