@dxos/react-ui-editor 0.4.8-main.6919ef3 → 0.4.8-main.6dbc1f1
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 +1388 -1298
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -0
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +12 -11
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +4 -2
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -0
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts +7 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +5 -1
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +0 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts +9 -0
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +7 -4
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts +6 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +1 -1
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useDocAccessor.d.ts +4 -2
- package/dist/types/src/hooks/useDocAccessor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.stories.d.ts +1 -0
- package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/package.json +26 -24
- package/src/components/TextEditor/TextEditor.stories.tsx +14 -2
- package/src/components/TextEditor/TextEditor.tsx +2 -2
- package/src/components/Toolbar/Toolbar.stories.tsx +23 -24
- package/src/components/Toolbar/Toolbar.tsx +102 -60
- package/src/extensions/automerge/automerge.ts +4 -4
- package/src/extensions/command/state.ts +2 -2
- package/src/extensions/comments.ts +2 -2
- package/src/extensions/dnd.ts +31 -9
- package/src/extensions/factories.ts +41 -15
- package/src/extensions/index.ts +0 -1
- package/src/extensions/markdown/action.ts +112 -0
- package/src/extensions/markdown/bundle.ts +8 -11
- package/src/extensions/markdown/formatting.test.ts +13 -13
- package/src/extensions/markdown/formatting.ts +95 -87
- package/src/extensions/markdown/image.ts +6 -0
- package/src/extensions/markdown/index.ts +1 -0
- package/src/extensions/modes.ts +8 -1
- package/src/hooks/useActionHandler.ts +4 -85
- package/src/hooks/useDocAccessor.ts +8 -2
- package/src/hooks/useTextEditor.stories.tsx +3 -3
- package/src/hooks/useTextEditor.ts +3 -0
- package/src/themes/default.ts +24 -8
- package/src/translations.ts +1 -0
- package/dist/types/src/extensions/cursor-line-margin.d.ts +0 -7
- package/dist/types/src/extensions/cursor-line-margin.d.ts.map +0 -1
- package/src/extensions/cursor-line-margin.ts +0 -94
|
@@ -15,6 +15,7 @@ var translations_default = [
|
|
|
15
15
|
"blockquote label": "Block quote",
|
|
16
16
|
"codeblock label": "Code block",
|
|
17
17
|
"comment label": "Create comment",
|
|
18
|
+
"image label": "Insert image",
|
|
18
19
|
"heading label": "Heading level",
|
|
19
20
|
"table label": "Create table"
|
|
20
21
|
}
|
|
@@ -23,17 +24,17 @@ var translations_default = [
|
|
|
23
24
|
];
|
|
24
25
|
|
|
25
26
|
// packages/ui/react-ui-editor/src/index.ts
|
|
26
|
-
import { keymap as
|
|
27
|
+
import { keymap as keymap11 } from "@codemirror/view";
|
|
27
28
|
import { tags as tags2 } from "@lezer/highlight";
|
|
28
29
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
29
30
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
30
31
|
|
|
31
32
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
32
33
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
33
|
-
import { EditorView as
|
|
34
|
+
import { EditorView as EditorView16 } from "@codemirror/view";
|
|
34
35
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
35
36
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
|
|
36
|
-
import { log as
|
|
37
|
+
import { log as log7 } from "@dxos/log";
|
|
37
38
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
38
39
|
|
|
39
40
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
|
@@ -121,8 +122,8 @@ var annotations = (options = {}) => {
|
|
|
121
122
|
annotationsState
|
|
122
123
|
], (state2) => {
|
|
123
124
|
const annotations2 = state2.field(annotationsState);
|
|
124
|
-
const decorations = annotations2.map((
|
|
125
|
-
const range = Cursor.getRangeFromCursor(state2,
|
|
125
|
+
const decorations = annotations2.map((annotation) => {
|
|
126
|
+
const range = Cursor.getRangeFromCursor(state2, annotation.cursor);
|
|
126
127
|
return range && annotationMark.range(range.from, range.to);
|
|
127
128
|
}).filter(isNotFalsy);
|
|
128
129
|
return Decoration.set(decorations);
|
|
@@ -474,13 +475,13 @@ var automerge = (accessor) => {
|
|
|
474
475
|
ViewPlugin.fromClass(class {
|
|
475
476
|
constructor(_view) {
|
|
476
477
|
this._view = _view;
|
|
477
|
-
|
|
478
|
+
this._handleChange = () => {
|
|
479
|
+
syncer.reconcile(this._view, false);
|
|
480
|
+
};
|
|
481
|
+
accessor.handle.addListener("change", this._handleChange);
|
|
478
482
|
}
|
|
479
483
|
destroy() {
|
|
480
|
-
accessor.handle.removeListener("change", this._handleChange
|
|
481
|
-
}
|
|
482
|
-
_handleChange() {
|
|
483
|
-
syncer.reconcile(this._view, false);
|
|
484
|
+
accessor.handle.removeListener("change", this._handleChange);
|
|
484
485
|
}
|
|
485
486
|
}),
|
|
486
487
|
// Reconcile local updates.
|
|
@@ -1195,7 +1196,7 @@ var commandState = StateField3.define({
|
|
|
1195
1196
|
}
|
|
1196
1197
|
});
|
|
1197
1198
|
}
|
|
1198
|
-
|
|
1199
|
+
requestAnimationFrame(() => view2.focus());
|
|
1199
1200
|
});
|
|
1200
1201
|
}
|
|
1201
1202
|
};
|
|
@@ -1831,14 +1832,14 @@ var focusComment = (view, id, center = true) => {
|
|
|
1831
1832
|
});
|
|
1832
1833
|
}
|
|
1833
1834
|
};
|
|
1834
|
-
var useComments = (view, id, comments2
|
|
1835
|
+
var useComments = (view, id, comments2) => {
|
|
1835
1836
|
useEffect(() => {
|
|
1836
1837
|
if (view) {
|
|
1837
1838
|
if (id === view.state.facet(documentId)) {
|
|
1838
1839
|
view.dispatch({
|
|
1839
1840
|
effects: setComments.of({
|
|
1840
1841
|
id,
|
|
1841
|
-
comments: comments2
|
|
1842
|
+
comments: comments2 ?? []
|
|
1842
1843
|
})
|
|
1843
1844
|
});
|
|
1844
1845
|
}
|
|
@@ -1850,76 +1851,14 @@ var useComments = (view, id, comments2 = []) => {
|
|
|
1850
1851
|
]);
|
|
1851
1852
|
};
|
|
1852
1853
|
|
|
1853
|
-
// packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
|
|
1854
|
-
import { Transaction } from "@codemirror/state";
|
|
1855
|
-
import { EditorView as EditorView8 } from "@codemirror/view";
|
|
1856
|
-
import { log as log5 } from "@dxos/log";
|
|
1857
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts";
|
|
1858
|
-
var annotation = "cursorLineMargin";
|
|
1859
|
-
var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
|
|
1860
|
-
var cursorLineMargin = (options = {
|
|
1861
|
-
lines: 3
|
|
1862
|
-
}) => {
|
|
1863
|
-
const { lines } = options;
|
|
1864
|
-
if (!lines || lines <= 0) {
|
|
1865
|
-
return [];
|
|
1866
|
-
}
|
|
1867
|
-
return EditorView8.updateListener.of(({ transactions, state: state2, selectionSet, startState, view }) => {
|
|
1868
|
-
if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
|
|
1869
|
-
return;
|
|
1870
|
-
}
|
|
1871
|
-
const s = state2;
|
|
1872
|
-
const { main } = s.selection;
|
|
1873
|
-
const rect = view.dom.getBoundingClientRect();
|
|
1874
|
-
const viewportTop = rect.top - view.documentTop;
|
|
1875
|
-
const viewportBottom = rect.bottom - view.documentTop;
|
|
1876
|
-
const mainLine = lineAtPos(s, main.head);
|
|
1877
|
-
const _visTopLine = lineAtPos(s, view.lineBlockAtHeight(viewportTop).from);
|
|
1878
|
-
const botLineBlk = view.lineBlockAtHeight(viewportBottom);
|
|
1879
|
-
const visBotLineDoc = lineAtPos(s, Math.min(botLineBlk.to, s.doc.length));
|
|
1880
|
-
const visBotLine = botLineBlk.bottom >= viewportBottom ? visBotLineDoc : visBotLineDoc + Math.floor((viewportBottom - botLineBlk.bottom) / view.defaultLineHeight);
|
|
1881
|
-
const needsScrollTop = false;
|
|
1882
|
-
const needsScrollBot = mainLine >= visBotLine - lines;
|
|
1883
|
-
if (needsScrollTop && needsScrollBot) {
|
|
1884
|
-
log5.warn("is cursorScrollMargin too large for the editor size?", void 0, {
|
|
1885
|
-
F: __dxlog_file6,
|
|
1886
|
-
L: 65,
|
|
1887
|
-
S: void 0,
|
|
1888
|
-
C: (f, a) => f(...a)
|
|
1889
|
-
});
|
|
1890
|
-
return;
|
|
1891
|
-
}
|
|
1892
|
-
if (!needsScrollTop && !needsScrollBot) {
|
|
1893
|
-
return;
|
|
1894
|
-
}
|
|
1895
|
-
if (selectionSet) {
|
|
1896
|
-
const { head } = startState.selection.main;
|
|
1897
|
-
const oldMainLine = lineAtPos(startState, head);
|
|
1898
|
-
if (needsScrollTop && oldMainLine < mainLine) {
|
|
1899
|
-
return;
|
|
1900
|
-
}
|
|
1901
|
-
if (needsScrollBot && oldMainLine > mainLine) {
|
|
1902
|
-
return;
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
view.dispatch({
|
|
1906
|
-
annotations: Transaction.userEvent.of(annotation),
|
|
1907
|
-
effects: EditorView8.scrollIntoView(s.selection.main.head, {
|
|
1908
|
-
y: needsScrollTop ? "start" : "end",
|
|
1909
|
-
yMargin: view.defaultLineHeight * lines
|
|
1910
|
-
})
|
|
1911
|
-
});
|
|
1912
|
-
});
|
|
1913
|
-
};
|
|
1914
|
-
|
|
1915
1854
|
// packages/ui/react-ui-editor/src/extensions/doc.ts
|
|
1916
1855
|
import { Facet as Facet5 } from "@codemirror/state";
|
|
1917
1856
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1918
|
-
var
|
|
1857
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/doc.ts";
|
|
1919
1858
|
var documentId2 = Facet5.define({
|
|
1920
1859
|
combine: (providers) => {
|
|
1921
1860
|
invariant3(providers.length <= 1, void 0, {
|
|
1922
|
-
F:
|
|
1861
|
+
F: __dxlog_file6,
|
|
1923
1862
|
L: 11,
|
|
1924
1863
|
S: void 0,
|
|
1925
1864
|
A: [
|
|
@@ -1932,33 +1871,51 @@ var documentId2 = Facet5.define({
|
|
|
1932
1871
|
});
|
|
1933
1872
|
|
|
1934
1873
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
1935
|
-
import { EditorView as
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1874
|
+
import { dropCursor, EditorView as EditorView8 } from "@codemirror/view";
|
|
1875
|
+
var styles4 = EditorView8.baseTheme({
|
|
1876
|
+
".cm-dropCursor": {
|
|
1877
|
+
borderLeft: `2px solid ${getToken("extend.colors.primary.500")}`,
|
|
1878
|
+
color: getToken("extend.colors.primary.500"),
|
|
1879
|
+
padding: "0 4px"
|
|
1880
|
+
},
|
|
1881
|
+
".cm-dropCursor:after": {
|
|
1882
|
+
content: '"\u2190"'
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
var dropFile = (options = {}) => {
|
|
1886
|
+
return [
|
|
1887
|
+
styles4,
|
|
1888
|
+
dropCursor(),
|
|
1889
|
+
EditorView8.domEventHandlers({
|
|
1890
|
+
drop: (event, view) => {
|
|
1891
|
+
event.preventDefault();
|
|
1892
|
+
const files = event.dataTransfer?.files;
|
|
1893
|
+
const pos = view.posAtCoords(event);
|
|
1894
|
+
if (files?.length && pos !== null) {
|
|
1895
|
+
view.dispatch({
|
|
1896
|
+
selection: {
|
|
1897
|
+
anchor: pos
|
|
1898
|
+
}
|
|
1899
|
+
});
|
|
1900
|
+
options.onDrop?.(view, {
|
|
1901
|
+
files
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
})
|
|
1906
|
+
];
|
|
1951
1907
|
};
|
|
1952
1908
|
|
|
1953
1909
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
1954
|
-
import { closeBrackets } from "@codemirror/autocomplete";
|
|
1955
|
-
import { history } from "@codemirror/commands";
|
|
1910
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
1911
|
+
import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
1956
1912
|
import { bracketMatching } from "@codemirror/language";
|
|
1913
|
+
import { searchKeymap } from "@codemirror/search";
|
|
1957
1914
|
import { EditorState } from "@codemirror/state";
|
|
1958
|
-
import { EditorView as
|
|
1915
|
+
import { EditorView as EditorView9, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap5, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
|
1959
1916
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
1960
1917
|
import { generateName } from "@dxos/display-name";
|
|
1961
|
-
import { log as
|
|
1918
|
+
import { log as log5 } from "@dxos/log";
|
|
1962
1919
|
import { hueTokens } from "@dxos/react-ui-theme";
|
|
1963
1920
|
import { hexToHue, isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
1964
1921
|
|
|
@@ -2163,50 +2120,75 @@ var defaultTheme = {
|
|
|
2163
2120
|
* </div>
|
|
2164
2121
|
* </div
|
|
2165
2122
|
*/
|
|
2166
|
-
".cm-panels": {
|
|
2167
|
-
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`
|
|
2168
|
-
},
|
|
2123
|
+
".cm-panels": {},
|
|
2169
2124
|
".cm-panel": {
|
|
2170
|
-
background: get3(tokens, "extend.colors.neutral.50"),
|
|
2171
2125
|
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
2172
2126
|
},
|
|
2127
|
+
".cm-panel input[type=checkbox]": {
|
|
2128
|
+
marginRight: "0.4rem !important"
|
|
2129
|
+
},
|
|
2130
|
+
"&light .cm-panel": {
|
|
2131
|
+
background: get3(tokens, "extend.colors.neutral.50")
|
|
2132
|
+
},
|
|
2133
|
+
"&dark .cm-panel": {
|
|
2134
|
+
background: get3(tokens, "extend.colors.neutral.850")
|
|
2135
|
+
},
|
|
2173
2136
|
".cm-button": {
|
|
2174
2137
|
margin: "4px",
|
|
2175
2138
|
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
2176
|
-
background: get3(tokens, "extend.colors.neutral.100"),
|
|
2177
2139
|
backgroundImage: "none",
|
|
2178
2140
|
border: "none",
|
|
2141
|
+
"&:active": {
|
|
2142
|
+
backgroundImage: "none"
|
|
2143
|
+
}
|
|
2144
|
+
},
|
|
2145
|
+
"&light .cm-button": {
|
|
2146
|
+
background: get3(tokens, "extend.colors.neutral.100"),
|
|
2179
2147
|
"&:hover": {
|
|
2180
2148
|
background: get3(tokens, "extend.colors.neutral.200")
|
|
2181
2149
|
},
|
|
2182
2150
|
"&:active": {
|
|
2183
|
-
background: get3(tokens, "extend.colors.neutral.300")
|
|
2184
|
-
backgroundImage: "none"
|
|
2151
|
+
background: get3(tokens, "extend.colors.neutral.300")
|
|
2185
2152
|
}
|
|
2186
2153
|
},
|
|
2187
|
-
".cm-
|
|
2188
|
-
|
|
2154
|
+
"&dark .cm-button": {
|
|
2155
|
+
background: get3(tokens, "extend.colors.neutral.800"),
|
|
2156
|
+
"&:hover": {
|
|
2157
|
+
background: get3(tokens, "extend.colors.neutral.700")
|
|
2158
|
+
},
|
|
2159
|
+
"&:active": {
|
|
2160
|
+
background: get3(tokens, "extend.colors.neutral.600")
|
|
2161
|
+
}
|
|
2189
2162
|
}
|
|
2190
2163
|
};
|
|
2191
2164
|
|
|
2192
2165
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
2193
|
-
var
|
|
2194
|
-
var
|
|
2166
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
|
2167
|
+
var defaultBasicOptions = {
|
|
2168
|
+
allowMultipleSelections: true,
|
|
2195
2169
|
bracketMatching: true,
|
|
2196
2170
|
closeBrackets: true,
|
|
2197
2171
|
drawSelection: true,
|
|
2198
2172
|
editable: true,
|
|
2199
2173
|
history: true,
|
|
2200
|
-
|
|
2174
|
+
keymap: "standard",
|
|
2175
|
+
lineWrapping: true,
|
|
2176
|
+
search: true
|
|
2177
|
+
};
|
|
2178
|
+
var keymaps = {
|
|
2179
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2180
|
+
standard: standardKeymap,
|
|
2181
|
+
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
2182
|
+
default: defaultKeymap
|
|
2201
2183
|
};
|
|
2202
2184
|
var createBasicExtensions = (_props) => {
|
|
2203
|
-
const props = defaultsDeep2({}, _props,
|
|
2185
|
+
const props = defaultsDeep2({}, _props, defaultBasicOptions);
|
|
2204
2186
|
return [
|
|
2205
|
-
//
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
F:
|
|
2209
|
-
L:
|
|
2187
|
+
// NOTE: Doesn't catch errors in keymap functions.
|
|
2188
|
+
EditorView9.exceptionSink.of((err) => {
|
|
2189
|
+
log5.catch(err, void 0, {
|
|
2190
|
+
F: __dxlog_file7,
|
|
2191
|
+
L: 91,
|
|
2210
2192
|
S: void 0,
|
|
2211
2193
|
C: (f, a) => f(...a)
|
|
2212
2194
|
});
|
|
@@ -2214,37 +2196,50 @@ var createBasicExtensions = (_props) => {
|
|
|
2214
2196
|
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2215
2197
|
props.bracketMatching && bracketMatching(),
|
|
2216
2198
|
props.closeBrackets && closeBrackets(),
|
|
2217
|
-
props.
|
|
2218
|
-
props.dropCursor && dropCursor(),
|
|
2199
|
+
props.dropCursor && dropCursor2(),
|
|
2219
2200
|
props.drawSelection && drawSelection(),
|
|
2220
2201
|
props.highlightActiveLine && highlightActiveLine(),
|
|
2221
2202
|
props.history && history(),
|
|
2222
2203
|
props.lineNumbers && lineNumbers(),
|
|
2223
|
-
props.lineWrapping &&
|
|
2204
|
+
props.lineWrapping && EditorView9.lineWrapping,
|
|
2224
2205
|
props.placeholder && placeholder(props.placeholder),
|
|
2225
2206
|
props.readonly && [
|
|
2226
2207
|
EditorState.readOnly.of(true),
|
|
2227
|
-
|
|
2208
|
+
EditorView9.editable.of(false)
|
|
2228
2209
|
],
|
|
2229
2210
|
props.scrollPastEnd && scrollPastEnd(),
|
|
2230
|
-
props.tabSize && EditorState.tabSize.of(props.tabSize)
|
|
2211
|
+
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
2212
|
+
// https://codemirror.net/docs/ref/#view.KeyBinding
|
|
2213
|
+
keymap5.of([
|
|
2214
|
+
...(props.keymap && keymaps[props.keymap]) ?? [],
|
|
2215
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2216
|
+
...props.indentWithTab ? [
|
|
2217
|
+
indentWithTab
|
|
2218
|
+
] : [],
|
|
2219
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
2220
|
+
...props.closeBrackets ? closeBracketsKeymap : [],
|
|
2221
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
2222
|
+
...props.history ? historyKeymap : [],
|
|
2223
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
2224
|
+
...props.search ? searchKeymap : []
|
|
2225
|
+
].filter(isNotFalsy2))
|
|
2231
2226
|
].filter(isNotFalsy2);
|
|
2232
2227
|
};
|
|
2233
|
-
var
|
|
2228
|
+
var defaultThemeSlots = {
|
|
2234
2229
|
editor: {
|
|
2235
2230
|
className: "w-full bs-full"
|
|
2236
2231
|
}
|
|
2237
2232
|
};
|
|
2238
2233
|
var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
|
|
2239
|
-
const slots = defaultsDeep2({}, _slots,
|
|
2234
|
+
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
|
2240
2235
|
return [
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
theme &&
|
|
2244
|
-
slots.editor?.className &&
|
|
2236
|
+
EditorView9.baseTheme(defaultTheme),
|
|
2237
|
+
EditorView9.darkTheme.of(themeMode === "dark"),
|
|
2238
|
+
theme && EditorView9.theme(theme),
|
|
2239
|
+
slots.editor?.className && EditorView9.editorAttributes.of({
|
|
2245
2240
|
class: slots.editor.className
|
|
2246
2241
|
}),
|
|
2247
|
-
slots.content?.className &&
|
|
2242
|
+
slots.content?.className && EditorView9.contentAttributes.of({
|
|
2248
2243
|
class: slots.content.className
|
|
2249
2244
|
})
|
|
2250
2245
|
].filter(isNotFalsy2);
|
|
@@ -2272,614 +2267,108 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
|
2272
2267
|
};
|
|
2273
2268
|
|
|
2274
2269
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
|
2275
|
-
import { EditorView as
|
|
2270
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
|
2276
2271
|
var listener = ({ onFocus, onChange }) => {
|
|
2277
2272
|
const extensions = [];
|
|
2278
|
-
onFocus && extensions.push(
|
|
2273
|
+
onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
|
|
2279
2274
|
onFocus(focusing);
|
|
2280
2275
|
return null;
|
|
2281
2276
|
}));
|
|
2282
|
-
onChange && extensions.push(
|
|
2277
|
+
onChange && extensions.push(EditorView10.updateListener.of((update2) => {
|
|
2283
2278
|
onChange(update2.state.doc.toString());
|
|
2284
2279
|
}));
|
|
2285
2280
|
return extensions;
|
|
2286
2281
|
};
|
|
2287
2282
|
|
|
2288
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
2289
|
-
import {
|
|
2290
|
-
import {
|
|
2291
|
-
import {
|
|
2292
|
-
import {
|
|
2293
|
-
import {
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2283
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
2284
|
+
import { snippet } from "@codemirror/autocomplete";
|
|
2285
|
+
import { syntaxTree } from "@codemirror/language";
|
|
2286
|
+
import { EditorSelection } from "@codemirror/state";
|
|
2287
|
+
import { EditorView as EditorView11, keymap as keymap6 } from "@codemirror/view";
|
|
2288
|
+
import { useMemo, useState } from "react";
|
|
2289
|
+
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;
|
|
2290
|
+
var Inline;
|
|
2291
|
+
(function(Inline2) {
|
|
2292
|
+
Inline2[Inline2["Strong"] = 0] = "Strong";
|
|
2293
|
+
Inline2[Inline2["Emphasis"] = 1] = "Emphasis";
|
|
2294
|
+
Inline2[Inline2["Strikethrough"] = 2] = "Strikethrough";
|
|
2295
|
+
Inline2[Inline2["Code"] = 3] = "Code";
|
|
2296
|
+
})(Inline || (Inline = {}));
|
|
2297
|
+
var List;
|
|
2298
|
+
(function(List2) {
|
|
2299
|
+
List2[List2["Ordered"] = 0] = "Ordered";
|
|
2300
|
+
List2[List2["Bullet"] = 1] = "Bullet";
|
|
2301
|
+
List2[List2["Task"] = 2] = "Task";
|
|
2302
|
+
})(List || (List = {}));
|
|
2303
|
+
var setHeading = (level) => ({ state: state2, dispatch }) => {
|
|
2304
|
+
const { selection: { ranges }, doc } = state2;
|
|
2305
|
+
const changes = [];
|
|
2306
|
+
let prevBlock = -1;
|
|
2307
|
+
for (const range of ranges) {
|
|
2308
|
+
let sawBlock = false;
|
|
2309
|
+
syntaxTree(state2).iterate({
|
|
2310
|
+
from: range.from,
|
|
2311
|
+
to: range.to,
|
|
2312
|
+
enter: (node) => {
|
|
2313
|
+
if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
|
|
2314
|
+
return;
|
|
2315
|
+
}
|
|
2316
|
+
sawBlock = true;
|
|
2317
|
+
prevBlock = node.from;
|
|
2318
|
+
const blockType = Textblocks[node.name];
|
|
2319
|
+
const isHeading = /heading(\d)/.exec(blockType);
|
|
2320
|
+
const curLevel = isHeading ? +isHeading[1] : node.name === "Paragraph" ? 0 : -1;
|
|
2321
|
+
if (curLevel < 0 || curLevel === level) {
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
if (curLevel === 0) {
|
|
2325
|
+
changes.push({
|
|
2326
|
+
from: node.from,
|
|
2327
|
+
insert: "#".repeat(level) + " "
|
|
2328
|
+
});
|
|
2329
|
+
} else if (node.name === "SetextHeading1" || node.name === "SetextHeading2") {
|
|
2330
|
+
const nextLine = doc.lineAt(node.to);
|
|
2331
|
+
if (level) {
|
|
2332
|
+
changes.push({
|
|
2333
|
+
from: node.from,
|
|
2334
|
+
insert: "#".repeat(level) + " "
|
|
2335
|
+
});
|
|
2336
|
+
}
|
|
2337
|
+
changes.push({
|
|
2338
|
+
from: nextLine.from - 1,
|
|
2339
|
+
to: nextLine.to
|
|
2340
|
+
});
|
|
2341
|
+
} else {
|
|
2342
|
+
if (level === 0) {
|
|
2343
|
+
changes.push({
|
|
2344
|
+
from: node.from,
|
|
2345
|
+
to: Math.min(node.to, node.from + curLevel + 1)
|
|
2346
|
+
});
|
|
2347
|
+
} else if (level < curLevel) {
|
|
2348
|
+
changes.push({
|
|
2349
|
+
from: node.from,
|
|
2350
|
+
to: node.from + (curLevel - level)
|
|
2351
|
+
});
|
|
2352
|
+
} else {
|
|
2353
|
+
changes.push({
|
|
2354
|
+
from: node.from,
|
|
2355
|
+
insert: "#".repeat(level - curLevel)
|
|
2356
|
+
});
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2361
|
+
let line;
|
|
2362
|
+
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
|
|
2363
|
+
changes.push({
|
|
2364
|
+
from: line.from,
|
|
2365
|
+
to: line.to,
|
|
2366
|
+
insert: "#".repeat(level) + " "
|
|
2367
|
+
});
|
|
2323
2368
|
}
|
|
2324
2369
|
}
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
Table,
|
|
2328
|
-
{
|
|
2329
|
-
props: [
|
|
2330
|
-
styleTags(markdownTags)
|
|
2331
|
-
]
|
|
2332
|
-
}
|
|
2333
|
-
];
|
|
2334
|
-
var markdownHighlightStyle = (readonly) => {
|
|
2335
|
-
return HighlightStyle.define([
|
|
2336
|
-
{
|
|
2337
|
-
tag: [
|
|
2338
|
-
tags.keyword,
|
|
2339
|
-
tags.name,
|
|
2340
|
-
tags.deleted,
|
|
2341
|
-
tags.character,
|
|
2342
|
-
tags.propertyName,
|
|
2343
|
-
tags.macroName,
|
|
2344
|
-
tags.color,
|
|
2345
|
-
tags.constant(tags.name),
|
|
2346
|
-
tags.standard(tags.name),
|
|
2347
|
-
tags.definition(tags.name),
|
|
2348
|
-
tags.separator,
|
|
2349
|
-
tags.typeName,
|
|
2350
|
-
tags.className,
|
|
2351
|
-
tags.number,
|
|
2352
|
-
tags.changed,
|
|
2353
|
-
tags.annotation,
|
|
2354
|
-
tags.modifier,
|
|
2355
|
-
tags.self,
|
|
2356
|
-
tags.namespace,
|
|
2357
|
-
tags.operator,
|
|
2358
|
-
tags.operatorKeyword,
|
|
2359
|
-
tags.escape,
|
|
2360
|
-
tags.regexp,
|
|
2361
|
-
tags.special(tags.string),
|
|
2362
|
-
tags.meta,
|
|
2363
|
-
tags.comment,
|
|
2364
|
-
tags.atom,
|
|
2365
|
-
tags.bool,
|
|
2366
|
-
tags.special(tags.variableName),
|
|
2367
|
-
tags.processingInstruction,
|
|
2368
|
-
tags.string,
|
|
2369
|
-
tags.inserted,
|
|
2370
|
-
tags.invalid
|
|
2371
|
-
],
|
|
2372
|
-
color: "inherit !important"
|
|
2373
|
-
},
|
|
2374
|
-
// Markdown marks.
|
|
2375
|
-
{
|
|
2376
|
-
tag: [
|
|
2377
|
-
tags.meta,
|
|
2378
|
-
tags.processingInstruction,
|
|
2379
|
-
markdownTags.LinkLabel,
|
|
2380
|
-
markdownTags.LinkReference,
|
|
2381
|
-
markdownTags.ListMark
|
|
2382
|
-
],
|
|
2383
|
-
class: mark
|
|
2384
|
-
},
|
|
2385
|
-
// Markdown marks.
|
|
2386
|
-
{
|
|
2387
|
-
tag: [
|
|
2388
|
-
markdownTags.CodeMark,
|
|
2389
|
-
markdownTags.HeaderMark,
|
|
2390
|
-
markdownTags.QuoteMark,
|
|
2391
|
-
markdownTags.EmphasisMark
|
|
2392
|
-
],
|
|
2393
|
-
class: mark
|
|
2394
|
-
},
|
|
2395
|
-
// E.g., code block language (after ```).
|
|
2396
|
-
{
|
|
2397
|
-
tag: [
|
|
2398
|
-
tags.function(tags.variableName),
|
|
2399
|
-
tags.labelName
|
|
2400
|
-
],
|
|
2401
|
-
class: codeMark
|
|
2402
|
-
},
|
|
2403
|
-
{
|
|
2404
|
-
tag: [
|
|
2405
|
-
tags.monospace
|
|
2406
|
-
],
|
|
2407
|
-
class: "font-mono"
|
|
2408
|
-
},
|
|
2409
|
-
// Headings.
|
|
2410
|
-
{
|
|
2411
|
-
tag: tags.heading1,
|
|
2412
|
-
class: heading(1)
|
|
2413
|
-
},
|
|
2414
|
-
{
|
|
2415
|
-
tag: tags.heading2,
|
|
2416
|
-
class: heading(2)
|
|
2417
|
-
},
|
|
2418
|
-
{
|
|
2419
|
-
tag: tags.heading3,
|
|
2420
|
-
class: heading(3)
|
|
2421
|
-
},
|
|
2422
|
-
{
|
|
2423
|
-
tag: tags.heading4,
|
|
2424
|
-
class: heading(4)
|
|
2425
|
-
},
|
|
2426
|
-
{
|
|
2427
|
-
tag: tags.heading5,
|
|
2428
|
-
class: heading(5)
|
|
2429
|
-
},
|
|
2430
|
-
{
|
|
2431
|
-
tag: tags.heading6,
|
|
2432
|
-
class: heading(6)
|
|
2433
|
-
},
|
|
2434
|
-
// Emphasis.
|
|
2435
|
-
{
|
|
2436
|
-
tag: tags.emphasis,
|
|
2437
|
-
class: italic
|
|
2438
|
-
},
|
|
2439
|
-
{
|
|
2440
|
-
tag: tags.strong,
|
|
2441
|
-
class: bold
|
|
2442
|
-
},
|
|
2443
|
-
{
|
|
2444
|
-
tag: tags.strikethrough,
|
|
2445
|
-
class: strikethrough
|
|
2446
|
-
},
|
|
2447
|
-
// Naked URLs.
|
|
2448
|
-
{
|
|
2449
|
-
tag: [
|
|
2450
|
-
markdownTags.URL
|
|
2451
|
-
],
|
|
2452
|
-
class: inlineUrl
|
|
2453
|
-
},
|
|
2454
|
-
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
2455
|
-
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
2456
|
-
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
2457
|
-
// the code, but all other CSS properties will be inherited.
|
|
2458
|
-
// IMPORTANT: Therefore, the fenced code block will use the base editor font unless changed by an extension.
|
|
2459
|
-
{
|
|
2460
|
-
tag: [
|
|
2461
|
-
markdownTags.CodeText,
|
|
2462
|
-
markdownTags.InlineCode
|
|
2463
|
-
],
|
|
2464
|
-
class: code
|
|
2465
|
-
},
|
|
2466
|
-
{
|
|
2467
|
-
tag: [
|
|
2468
|
-
markdownTags.QuoteMark
|
|
2469
|
-
],
|
|
2470
|
-
class: blockquote
|
|
2471
|
-
},
|
|
2472
|
-
{
|
|
2473
|
-
tag: [
|
|
2474
|
-
markdownTags.TableCell
|
|
2475
|
-
],
|
|
2476
|
-
class: "font-mono"
|
|
2477
|
-
}
|
|
2478
|
-
], {
|
|
2479
|
-
scope: markdownLanguage2,
|
|
2480
|
-
all: {
|
|
2481
|
-
fontFamily: getToken("fontFamily.body", []).join(",")
|
|
2482
|
-
}
|
|
2483
|
-
});
|
|
2484
|
-
};
|
|
2485
|
-
|
|
2486
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
2487
|
-
var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
2488
|
-
return [
|
|
2489
|
-
// Main extension.
|
|
2490
|
-
// https://github.com/codemirror/lang-markdown
|
|
2491
|
-
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
2492
|
-
markdown({
|
|
2493
|
-
// GRM by default (vs strict CommonMark):
|
|
2494
|
-
// Table, TaskList, Strikethrough, and Autolink.
|
|
2495
|
-
// NOTE: This extends the parser; it doesn't affect rendering.
|
|
2496
|
-
// https://github.github.com/gfm
|
|
2497
|
-
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
2498
|
-
base: markdownLanguage3,
|
|
2499
|
-
// Languages for syntax highlighting fenced code blocks.
|
|
2500
|
-
codeLanguages: languages,
|
|
2501
|
-
// Parser extensions.
|
|
2502
|
-
extensions: [
|
|
2503
|
-
// GFM provided by default.
|
|
2504
|
-
markdownTagsExtensions
|
|
2505
|
-
]
|
|
2506
|
-
}),
|
|
2507
|
-
// https://github.com/codemirror/theme-one-dark
|
|
2508
|
-
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
2509
|
-
// Custom styles.
|
|
2510
|
-
syntaxHighlighting(markdownHighlightStyle()),
|
|
2511
|
-
keymap5.of([
|
|
2512
|
-
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2513
|
-
indentWithTab,
|
|
2514
|
-
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
2515
|
-
...closeBracketsKeymap,
|
|
2516
|
-
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
2517
|
-
...historyKeymap,
|
|
2518
|
-
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
2519
|
-
...searchKeymap,
|
|
2520
|
-
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2521
|
-
...standardKeymap
|
|
2522
|
-
])
|
|
2523
|
-
];
|
|
2524
|
-
};
|
|
2525
|
-
|
|
2526
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
2527
|
-
import { syntaxTree } from "@codemirror/language";
|
|
2528
|
-
import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
2529
|
-
import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
2530
|
-
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
2531
|
-
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
2532
|
-
toDOM() {
|
|
2533
|
-
const el = document.createElement("span");
|
|
2534
|
-
el.className = "cm-hr";
|
|
2535
|
-
return el;
|
|
2536
|
-
}
|
|
2537
|
-
};
|
|
2538
|
-
var LinkButton = class extends WidgetType3 {
|
|
2539
|
-
constructor(url, render) {
|
|
2540
|
-
super();
|
|
2541
|
-
this.url = url;
|
|
2542
|
-
this.render = render;
|
|
2543
|
-
}
|
|
2544
|
-
eq(other) {
|
|
2545
|
-
return this.url === other.url;
|
|
2546
|
-
}
|
|
2547
|
-
toDOM(view) {
|
|
2548
|
-
const el = document.createElement("span");
|
|
2549
|
-
this.render(el, this.url);
|
|
2550
|
-
return el;
|
|
2551
|
-
}
|
|
2552
|
-
};
|
|
2553
|
-
var CheckboxWidget = class extends WidgetType3 {
|
|
2554
|
-
constructor(_checked) {
|
|
2555
|
-
super();
|
|
2556
|
-
this._checked = _checked;
|
|
2557
|
-
}
|
|
2558
|
-
eq(other) {
|
|
2559
|
-
return this._checked === other._checked;
|
|
2560
|
-
}
|
|
2561
|
-
toDOM(view) {
|
|
2562
|
-
const input = document.createElement("input");
|
|
2563
|
-
input.className = "cm-task-checkbox ch-checkbox ch-focus-ring -mbs-0.5";
|
|
2564
|
-
input.type = "checkbox";
|
|
2565
|
-
input.checked = this._checked;
|
|
2566
|
-
if (view.state.readOnly) {
|
|
2567
|
-
input.setAttribute("disabled", "true");
|
|
2568
|
-
} else {
|
|
2569
|
-
input.onmousedown = (event) => {
|
|
2570
|
-
const pos = view.posAtDOM(input);
|
|
2571
|
-
const text = view.state.sliceDoc(pos, pos + 3);
|
|
2572
|
-
if (text === (this._checked ? "[x]" : "[ ]")) {
|
|
2573
|
-
view.dispatch({
|
|
2574
|
-
changes: {
|
|
2575
|
-
from: pos + 1,
|
|
2576
|
-
to: pos + 2,
|
|
2577
|
-
insert: this._checked ? " " : "x"
|
|
2578
|
-
}
|
|
2579
|
-
});
|
|
2580
|
-
event.preventDefault();
|
|
2581
|
-
}
|
|
2582
|
-
};
|
|
2583
|
-
}
|
|
2584
|
-
return input;
|
|
2585
|
-
}
|
|
2586
|
-
ignoreEvent() {
|
|
2587
|
-
return false;
|
|
2588
|
-
}
|
|
2589
|
-
};
|
|
2590
|
-
var hide = Decoration5.replace({});
|
|
2591
|
-
var fencedCodeLine = Decoration5.line({
|
|
2592
|
-
class: mx2("cm-code cm-codeblock-line")
|
|
2593
|
-
});
|
|
2594
|
-
var fencedCodeLineFirst = Decoration5.line({
|
|
2595
|
-
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
|
2596
|
-
});
|
|
2597
|
-
var fencedCodeLineLast = Decoration5.line({
|
|
2598
|
-
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
|
2599
|
-
});
|
|
2600
|
-
var horizontalRule = Decoration5.replace({
|
|
2601
|
-
widget: new HorizontalRuleWidget()
|
|
2602
|
-
});
|
|
2603
|
-
var checkedTask = Decoration5.replace({
|
|
2604
|
-
widget: new CheckboxWidget(true)
|
|
2605
|
-
});
|
|
2606
|
-
var uncheckedTask = Decoration5.replace({
|
|
2607
|
-
widget: new CheckboxWidget(false)
|
|
2608
|
-
});
|
|
2609
|
-
var editingRange = (state2, range, focus) => {
|
|
2610
|
-
const { readOnly, selection: { main: { head } } } = state2;
|
|
2611
|
-
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
2612
|
-
};
|
|
2613
|
-
var MarksByParent = /* @__PURE__ */ new Set([
|
|
2614
|
-
"CodeMark",
|
|
2615
|
-
"EmphasisMark",
|
|
2616
|
-
"StrikethroughMark",
|
|
2617
|
-
"SubscriptMark",
|
|
2618
|
-
"SuperscriptMark"
|
|
2619
|
-
]);
|
|
2620
|
-
var buildDecorations = (view, options, focus) => {
|
|
2621
|
-
const deco = new RangeSetBuilder2();
|
|
2622
|
-
const atomicDeco = new RangeSetBuilder2();
|
|
2623
|
-
const { state: state2 } = view;
|
|
2624
|
-
for (const { from, to } of view.visibleRanges) {
|
|
2625
|
-
syntaxTree(state2).iterate({
|
|
2626
|
-
from,
|
|
2627
|
-
to,
|
|
2628
|
-
enter: (node) => {
|
|
2629
|
-
if (node.name === "FencedCode") {
|
|
2630
|
-
const editing = editingRange(state2, node, focus);
|
|
2631
|
-
for (const block of view.viewportLineBlocks) {
|
|
2632
|
-
if (block.to < node.from) {
|
|
2633
|
-
continue;
|
|
2634
|
-
}
|
|
2635
|
-
if (block.from > node.to) {
|
|
2636
|
-
break;
|
|
2637
|
-
}
|
|
2638
|
-
const first = block.from <= node.from;
|
|
2639
|
-
const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
|
|
2640
|
-
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
2641
|
-
if (!editing && (first || last)) {
|
|
2642
|
-
atomicDeco.add(block.from, block.to, hide);
|
|
2643
|
-
}
|
|
2644
|
-
}
|
|
2645
|
-
return false;
|
|
2646
|
-
} else if (node.name === "Link") {
|
|
2647
|
-
const marks = node.node.getChildren("LinkMark");
|
|
2648
|
-
const urlNode = node.node.getChild("URL");
|
|
2649
|
-
const editing = editingRange(state2, node, focus);
|
|
2650
|
-
if (urlNode && marks.length >= 2) {
|
|
2651
|
-
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
2652
|
-
if (!editing) {
|
|
2653
|
-
atomicDeco.add(node.from, marks[0].to, hide);
|
|
2654
|
-
}
|
|
2655
|
-
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
2656
|
-
tagName: "a",
|
|
2657
|
-
attributes: {
|
|
2658
|
-
class: "cm-link",
|
|
2659
|
-
href: url,
|
|
2660
|
-
rel: "noreferrer",
|
|
2661
|
-
target: "_blank"
|
|
2662
|
-
}
|
|
2663
|
-
}));
|
|
2664
|
-
if (!editing) {
|
|
2665
|
-
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
|
|
2666
|
-
widget: new LinkButton(url, options.renderLinkButton)
|
|
2667
|
-
}) : hide);
|
|
2668
|
-
}
|
|
2669
|
-
}
|
|
2670
|
-
} else if (node.name === "HeaderMark") {
|
|
2671
|
-
const parent = node.node.parent;
|
|
2672
|
-
if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
|
|
2673
|
-
const next = state2.doc.sliceString(node.to, node.to + 1);
|
|
2674
|
-
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2675
|
-
}
|
|
2676
|
-
} else if (node.name === "HorizontalRule") {
|
|
2677
|
-
if (!editingRange(state2, node, focus)) {
|
|
2678
|
-
deco.add(node.from, node.to, horizontalRule);
|
|
2679
|
-
}
|
|
2680
|
-
} else if (node.name === "TaskMarker") {
|
|
2681
|
-
if (!editingRange(state2, node, focus)) {
|
|
2682
|
-
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2683
|
-
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
2684
|
-
class: "cm-task"
|
|
2685
|
-
}));
|
|
2686
|
-
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2687
|
-
}
|
|
2688
|
-
} else if (MarksByParent.has(node.name)) {
|
|
2689
|
-
if (!editingRange(state2, node.node.parent, focus)) {
|
|
2690
|
-
atomicDeco.add(node.from, node.to, hide);
|
|
2691
|
-
}
|
|
2692
|
-
}
|
|
2693
|
-
}
|
|
2694
|
-
});
|
|
2695
|
-
}
|
|
2696
|
-
return {
|
|
2697
|
-
deco: deco.finish(),
|
|
2698
|
-
atomicDeco: atomicDeco.finish()
|
|
2699
|
-
};
|
|
2700
|
-
};
|
|
2701
|
-
var forceUpdate = StateEffect4.define();
|
|
2702
|
-
var decorateMarkdown = (options = {}) => {
|
|
2703
|
-
return [
|
|
2704
|
-
ViewPlugin4.fromClass(class {
|
|
2705
|
-
constructor(view) {
|
|
2706
|
-
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
|
|
2707
|
-
}
|
|
2708
|
-
update(update2) {
|
|
2709
|
-
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
|
2710
|
-
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
|
|
2711
|
-
this.clearUpdate();
|
|
2712
|
-
} else if (update2.selectionSet) {
|
|
2713
|
-
this.scheduleUpdate(update2.view);
|
|
2714
|
-
}
|
|
2715
|
-
}
|
|
2716
|
-
// TODO(burdon): BUG: If the cursor is at the end of a link at the end of a line,
|
|
2717
|
-
// the cursor will float in space or be in the wrong position after the decoration is applied.
|
|
2718
|
-
scheduleUpdate(view) {
|
|
2719
|
-
this.clearUpdate();
|
|
2720
|
-
this.pendingUpdate = setTimeout(() => {
|
|
2721
|
-
view.dispatch({
|
|
2722
|
-
effects: forceUpdate.of(null)
|
|
2723
|
-
});
|
|
2724
|
-
}, options.selectionChangeDelay);
|
|
2725
|
-
}
|
|
2726
|
-
clearUpdate() {
|
|
2727
|
-
if (this.pendingUpdate) {
|
|
2728
|
-
clearTimeout(this.pendingUpdate);
|
|
2729
|
-
this.pendingUpdate = void 0;
|
|
2730
|
-
}
|
|
2731
|
-
}
|
|
2732
|
-
destroy() {
|
|
2733
|
-
this.clearUpdate();
|
|
2734
|
-
}
|
|
2735
|
-
}, {
|
|
2736
|
-
provide: (plugin) => [
|
|
2737
|
-
EditorView12.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2738
|
-
EditorView12.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
2739
|
-
EditorView12.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration5.none)
|
|
2740
|
-
]
|
|
2741
|
-
}),
|
|
2742
|
-
formattingStyles
|
|
2743
|
-
];
|
|
2744
|
-
};
|
|
2745
|
-
var formattingStyles = EditorView12.baseTheme({
|
|
2746
|
-
"& .cm-code": {
|
|
2747
|
-
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2748
|
-
},
|
|
2749
|
-
"& .cm-codeblock-line": {
|
|
2750
|
-
paddingInline: "1rem !important"
|
|
2751
|
-
},
|
|
2752
|
-
"& .cm-codeblock-end": {
|
|
2753
|
-
display: "inline-block",
|
|
2754
|
-
width: "100%",
|
|
2755
|
-
position: "relative",
|
|
2756
|
-
"&::after": {
|
|
2757
|
-
position: "absolute",
|
|
2758
|
-
inset: 0,
|
|
2759
|
-
content: '""'
|
|
2760
|
-
}
|
|
2761
|
-
},
|
|
2762
|
-
"& .cm-codeblock-first": {
|
|
2763
|
-
borderTopLeftRadius: ".5rem",
|
|
2764
|
-
borderTopRightRadius: ".5rem"
|
|
2765
|
-
},
|
|
2766
|
-
"& .cm-codeblock-last": {
|
|
2767
|
-
borderBottomLeftRadius: ".5rem",
|
|
2768
|
-
borderBottomRightRadius: ".5rem"
|
|
2769
|
-
},
|
|
2770
|
-
"&light .cm-codeblock-line, &light .cm-activeLine.cm-codeblock-line": {
|
|
2771
|
-
background: getToken("extend.semanticColors.input.light"),
|
|
2772
|
-
mixBlendMode: "darken"
|
|
2773
|
-
},
|
|
2774
|
-
"&dark .cm-codeblock-line, &dark .cm-activeLine.cm-codeblock-line": {
|
|
2775
|
-
background: getToken("extend.semanticColors.input.dark"),
|
|
2776
|
-
mixBlendMode: "lighten"
|
|
2777
|
-
},
|
|
2778
|
-
"& .cm-hr": {
|
|
2779
|
-
display: "inline-block",
|
|
2780
|
-
width: "100%",
|
|
2781
|
-
height: "0",
|
|
2782
|
-
verticalAlign: "middle",
|
|
2783
|
-
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
2784
|
-
},
|
|
2785
|
-
"& .cm-task": {
|
|
2786
|
-
color: getToken("extend.colors.blue.500")
|
|
2787
|
-
},
|
|
2788
|
-
"& .cm-task-checkbox": {
|
|
2789
|
-
marginLeft: "4px",
|
|
2790
|
-
marginRight: "4px"
|
|
2791
|
-
}
|
|
2792
|
-
});
|
|
2793
|
-
|
|
2794
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
2795
|
-
import { snippet } from "@codemirror/autocomplete";
|
|
2796
|
-
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2797
|
-
import { EditorSelection } from "@codemirror/state";
|
|
2798
|
-
import { EditorView as EditorView13, keymap as keymap6 } from "@codemirror/view";
|
|
2799
|
-
import { useState, useMemo } from "react";
|
|
2800
|
-
var compareFormatting = (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;
|
|
2801
|
-
var Inline;
|
|
2802
|
-
(function(Inline2) {
|
|
2803
|
-
Inline2[Inline2["Strong"] = 0] = "Strong";
|
|
2804
|
-
Inline2[Inline2["Emphasis"] = 1] = "Emphasis";
|
|
2805
|
-
Inline2[Inline2["Strikethrough"] = 2] = "Strikethrough";
|
|
2806
|
-
Inline2[Inline2["Code"] = 3] = "Code";
|
|
2807
|
-
})(Inline || (Inline = {}));
|
|
2808
|
-
var List;
|
|
2809
|
-
(function(List2) {
|
|
2810
|
-
List2[List2["Ordered"] = 0] = "Ordered";
|
|
2811
|
-
List2[List2["Bullet"] = 1] = "Bullet";
|
|
2812
|
-
List2[List2["Task"] = 2] = "Task";
|
|
2813
|
-
})(List || (List = {}));
|
|
2814
|
-
var setHeading = (level) => ({ state: state2, dispatch }) => {
|
|
2815
|
-
const { selection: { ranges }, doc } = state2;
|
|
2816
|
-
const changes = [];
|
|
2817
|
-
let prevBlock = -1;
|
|
2818
|
-
for (const range of ranges) {
|
|
2819
|
-
let sawBlock = false;
|
|
2820
|
-
syntaxTree2(state2).iterate({
|
|
2821
|
-
from: range.from,
|
|
2822
|
-
to: range.to,
|
|
2823
|
-
enter: (node) => {
|
|
2824
|
-
if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
|
|
2825
|
-
return;
|
|
2826
|
-
}
|
|
2827
|
-
sawBlock = true;
|
|
2828
|
-
prevBlock = node.from;
|
|
2829
|
-
const blockType = Textblocks[node.name];
|
|
2830
|
-
const isHeading = /heading(\d)/.exec(blockType);
|
|
2831
|
-
const curLevel = isHeading ? +isHeading[1] : node.name === "Paragraph" ? 0 : -1;
|
|
2832
|
-
if (curLevel < 0 || curLevel === level) {
|
|
2833
|
-
return;
|
|
2834
|
-
}
|
|
2835
|
-
if (curLevel === 0) {
|
|
2836
|
-
changes.push({
|
|
2837
|
-
from: node.from,
|
|
2838
|
-
insert: "#".repeat(level) + " "
|
|
2839
|
-
});
|
|
2840
|
-
} else if (node.name === "SetextHeading1" || node.name === "SetextHeading2") {
|
|
2841
|
-
const nextLine = doc.lineAt(node.to);
|
|
2842
|
-
if (level) {
|
|
2843
|
-
changes.push({
|
|
2844
|
-
from: node.from,
|
|
2845
|
-
insert: "#".repeat(level) + " "
|
|
2846
|
-
});
|
|
2847
|
-
}
|
|
2848
|
-
changes.push({
|
|
2849
|
-
from: nextLine.from - 1,
|
|
2850
|
-
to: nextLine.to
|
|
2851
|
-
});
|
|
2852
|
-
} else {
|
|
2853
|
-
if (level === 0) {
|
|
2854
|
-
changes.push({
|
|
2855
|
-
from: node.from,
|
|
2856
|
-
to: Math.min(node.to, node.from + curLevel + 1)
|
|
2857
|
-
});
|
|
2858
|
-
} else if (level < curLevel) {
|
|
2859
|
-
changes.push({
|
|
2860
|
-
from: node.from,
|
|
2861
|
-
to: node.from + (curLevel - level)
|
|
2862
|
-
});
|
|
2863
|
-
} else {
|
|
2864
|
-
changes.push({
|
|
2865
|
-
from: node.from,
|
|
2866
|
-
insert: "#".repeat(level - curLevel)
|
|
2867
|
-
});
|
|
2868
|
-
}
|
|
2869
|
-
}
|
|
2870
|
-
}
|
|
2871
|
-
});
|
|
2872
|
-
let line;
|
|
2873
|
-
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
|
|
2874
|
-
changes.push({
|
|
2875
|
-
from: line.from,
|
|
2876
|
-
to: line.to,
|
|
2877
|
-
insert: "#".repeat(level) + " "
|
|
2878
|
-
});
|
|
2879
|
-
}
|
|
2880
|
-
}
|
|
2881
|
-
if (!changes.length) {
|
|
2882
|
-
return false;
|
|
2370
|
+
if (!changes.length) {
|
|
2371
|
+
return false;
|
|
2883
2372
|
}
|
|
2884
2373
|
const changeSet = state2.changes(changes);
|
|
2885
2374
|
dispatch(state2.update({
|
|
@@ -2924,7 +2413,7 @@ var setStyle = (type, enable) => ({ state: state2, dispatch }) => {
|
|
|
2924
2413
|
let startCovered = false;
|
|
2925
2414
|
let endCovered = false;
|
|
2926
2415
|
let { from, to } = range;
|
|
2927
|
-
|
|
2416
|
+
syntaxTree(state2).iterate({
|
|
2928
2417
|
from,
|
|
2929
2418
|
to,
|
|
2930
2419
|
enter: (node) => {
|
|
@@ -3124,7 +2613,7 @@ var insertTable = (view) => {
|
|
|
3124
2613
|
snippets.table(view, null, from, from);
|
|
3125
2614
|
};
|
|
3126
2615
|
var removeLinkInner = (from, to, changes, state2) => {
|
|
3127
|
-
|
|
2616
|
+
syntaxTree(state2).iterate({
|
|
3128
2617
|
from,
|
|
3129
2618
|
to,
|
|
3130
2619
|
enter: (node) => {
|
|
@@ -3163,12 +2652,12 @@ var removeLink = ({ state: state2, dispatch }) => {
|
|
|
3163
2652
|
}));
|
|
3164
2653
|
return true;
|
|
3165
2654
|
};
|
|
3166
|
-
var addLink = ({ state: state2, dispatch }) => {
|
|
2655
|
+
var addLink = ({ url, image: image2 } = {}) => ({ state: state2, dispatch }) => {
|
|
3167
2656
|
const changes = state2.changeByRange((range) => {
|
|
3168
2657
|
let { from, to } = range;
|
|
3169
2658
|
const cutStyles = [];
|
|
3170
2659
|
let okay = null;
|
|
3171
|
-
|
|
2660
|
+
syntaxTree(state2).iterate({
|
|
3172
2661
|
from,
|
|
3173
2662
|
to,
|
|
3174
2663
|
enter: (node) => {
|
|
@@ -3234,15 +2723,15 @@ var addLink = ({ state: state2, dispatch }) => {
|
|
|
3234
2723
|
}
|
|
3235
2724
|
changes2.push({
|
|
3236
2725
|
from,
|
|
3237
|
-
insert: "["
|
|
2726
|
+
insert: image2 ? "`
|
|
3241
2730
|
});
|
|
3242
2731
|
const changeSet = state2.changes(changes2.concat(changesAfter));
|
|
3243
2732
|
return {
|
|
3244
2733
|
changes: changeSet,
|
|
3245
|
-
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
|
|
2734
|
+
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
|
|
3246
2735
|
};
|
|
3247
2736
|
});
|
|
3248
2737
|
if (changes.changes.empty) {
|
|
@@ -3261,7 +2750,7 @@ var addList = (type) => ({ state: state2, dispatch }) => {
|
|
|
3261
2750
|
let parentColumn = null;
|
|
3262
2751
|
const blocks = [];
|
|
3263
2752
|
for (const { from, to } of state2.selection.ranges) {
|
|
3264
|
-
|
|
2753
|
+
syntaxTree(state2).iterate({
|
|
3265
2754
|
from,
|
|
3266
2755
|
to,
|
|
3267
2756
|
enter: (node) => {
|
|
@@ -3348,541 +2837,1097 @@ var addList = (type) => ({ state: state2, dispatch }) => {
|
|
|
3348
2837
|
if (blocks[j].counter !== max + 1) {
|
|
3349
2838
|
break;
|
|
3350
2839
|
}
|
|
3351
|
-
max++;
|
|
2840
|
+
max++;
|
|
2841
|
+
}
|
|
2842
|
+
const num = String(counter2);
|
|
2843
|
+
padding = Math.max(String(max).length, padding);
|
|
2844
|
+
mark2 = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
|
|
2845
|
+
} else {
|
|
2846
|
+
mark2 = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
|
|
2847
|
+
}
|
|
2848
|
+
changes.push({
|
|
2849
|
+
from: nodeFrom,
|
|
2850
|
+
insert: mark2
|
|
2851
|
+
});
|
|
2852
|
+
while (line.to < node.to) {
|
|
2853
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
2854
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2855
|
+
changes.push({
|
|
2856
|
+
from: line.from + Math.min(open, column),
|
|
2857
|
+
insert: " ".repeat(mark2.length)
|
|
2858
|
+
});
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
if (type === 0) {
|
|
2862
|
+
const last = blocks[blocks.length - 1];
|
|
2863
|
+
let next = last.node.nextSibling;
|
|
2864
|
+
while (next && /Mark$/.test(next.name)) {
|
|
2865
|
+
next = next.nextSibling;
|
|
2866
|
+
}
|
|
2867
|
+
if (next?.name === "OrderedList") {
|
|
2868
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
const changeSet = state2.changes(changes);
|
|
2872
|
+
dispatch(state2.update({
|
|
2873
|
+
changes: changeSet,
|
|
2874
|
+
selection: state2.selection.map(changeSet, 1),
|
|
2875
|
+
userEvent: "format.list.add",
|
|
2876
|
+
scrollIntoView: true
|
|
2877
|
+
}));
|
|
2878
|
+
return true;
|
|
2879
|
+
};
|
|
2880
|
+
var removeList = (type) => ({ state: state2, dispatch }) => {
|
|
2881
|
+
let lastBlock = -1;
|
|
2882
|
+
const changes = [];
|
|
2883
|
+
const stack = [];
|
|
2884
|
+
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
2885
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
2886
|
+
syntaxTree(state2).iterate({
|
|
2887
|
+
from,
|
|
2888
|
+
to,
|
|
2889
|
+
enter: (node) => {
|
|
2890
|
+
const { name } = node;
|
|
2891
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2892
|
+
stack.push(name);
|
|
2893
|
+
} else if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
2894
|
+
stack[stack.length - 1] = "TaskList";
|
|
2895
|
+
}
|
|
2896
|
+
},
|
|
2897
|
+
leave: (node) => {
|
|
2898
|
+
const { name } = node;
|
|
2899
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2900
|
+
stack.pop();
|
|
2901
|
+
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
2902
|
+
lastBlock = node.from;
|
|
2903
|
+
let line = state2.doc.lineAt(node.from);
|
|
2904
|
+
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
2905
|
+
if (!mark2) {
|
|
2906
|
+
return false;
|
|
2907
|
+
}
|
|
2908
|
+
const column = node.from - line.from;
|
|
2909
|
+
changes.push({
|
|
2910
|
+
from: node.from,
|
|
2911
|
+
to: node.from + mark2[0].length
|
|
2912
|
+
});
|
|
2913
|
+
while (line.to < node.to) {
|
|
2914
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
2915
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2916
|
+
if (open > column) {
|
|
2917
|
+
changes.push({
|
|
2918
|
+
from: line.from + column,
|
|
2919
|
+
to: line.from + Math.min(column + mark2[0].length, open)
|
|
2920
|
+
});
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
if (node.to >= to) {
|
|
2924
|
+
renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
|
|
2925
|
+
}
|
|
2926
|
+
return false;
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
});
|
|
2930
|
+
}
|
|
2931
|
+
if (!changes.length) {
|
|
2932
|
+
return false;
|
|
2933
|
+
}
|
|
2934
|
+
dispatch(state2.update({
|
|
2935
|
+
changes,
|
|
2936
|
+
userEvent: "format.list.remove",
|
|
2937
|
+
scrollIntoView: true
|
|
2938
|
+
}));
|
|
2939
|
+
return true;
|
|
2940
|
+
};
|
|
2941
|
+
var toggleList = (type) => (target) => {
|
|
2942
|
+
const formatting = getFormatting(target.state);
|
|
2943
|
+
const active = formatting.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
|
|
2944
|
+
return (active ? removeList(type) : addList(type))(target);
|
|
2945
|
+
};
|
|
2946
|
+
var renumberListItems = (item, counter, changes, doc) => {
|
|
2947
|
+
for (; item; item = item.nextSibling) {
|
|
2948
|
+
if (item.name === "ListItem") {
|
|
2949
|
+
const number = /(\s*)(\d+)[.)]/.exec(doc.sliceString(item.from, item.from + 10));
|
|
2950
|
+
if (!number || +number[2] === counter) {
|
|
2951
|
+
break;
|
|
2952
|
+
}
|
|
2953
|
+
const size = number[1].length + number[2].length;
|
|
2954
|
+
const newNum = String(counter);
|
|
2955
|
+
changes.push({
|
|
2956
|
+
from: item.from + Math.max(0, size - newNum.length),
|
|
2957
|
+
to: item.from + size,
|
|
2958
|
+
insert: newNum
|
|
2959
|
+
});
|
|
2960
|
+
counter++;
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
};
|
|
2964
|
+
var setBlockquote = (enable) => ({ state: state2, dispatch }) => {
|
|
2965
|
+
const lines = [];
|
|
2966
|
+
let lastBlock = -1;
|
|
2967
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
2968
|
+
const sawBlock = false;
|
|
2969
|
+
syntaxTree(state2).iterate({
|
|
2970
|
+
from,
|
|
2971
|
+
to,
|
|
2972
|
+
enter: (node) => {
|
|
2973
|
+
if (Object.hasOwn(Textblocks, node.name) || node.name === "Table") {
|
|
2974
|
+
if (node.from === lastBlock) {
|
|
2975
|
+
return false;
|
|
2976
|
+
}
|
|
2977
|
+
lastBlock = node.from;
|
|
2978
|
+
let line2 = state2.doc.lineAt(node.from);
|
|
2979
|
+
if (line2.number > 1) {
|
|
2980
|
+
const prevLine = state2.doc.line(line2.number - 1);
|
|
2981
|
+
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
2982
|
+
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
2983
|
+
lines.push(prevLine);
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
for (; ; ) {
|
|
2988
|
+
lines.push(line2);
|
|
2989
|
+
if (line2.to >= node.to) {
|
|
2990
|
+
break;
|
|
2991
|
+
}
|
|
2992
|
+
line2 = state2.doc.line(line2.number + 1);
|
|
2993
|
+
}
|
|
2994
|
+
if (!enable && line2.number < state2.doc.lines) {
|
|
2995
|
+
const nextLine = state2.doc.line(line2.number + 1);
|
|
2996
|
+
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
2997
|
+
lines.push(nextLine);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
return false;
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
3003
|
+
});
|
|
3004
|
+
let line;
|
|
3005
|
+
if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
|
|
3006
|
+
lines.push(line);
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
const changes = [];
|
|
3010
|
+
for (const line of lines) {
|
|
3011
|
+
if (enable) {
|
|
3012
|
+
changes.push({
|
|
3013
|
+
from: line.from,
|
|
3014
|
+
insert: /\S/.test(line.text) ? "> " : ">"
|
|
3015
|
+
});
|
|
3016
|
+
} else {
|
|
3017
|
+
const quote = /((?:[\s>\-+*]|\d+[.)])*?)> ?/.exec(line.text);
|
|
3018
|
+
if (quote) {
|
|
3019
|
+
changes.push({
|
|
3020
|
+
from: line.from + quote[1].length,
|
|
3021
|
+
to: line.from + quote[0].length
|
|
3022
|
+
});
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
if (!changes.length) {
|
|
3027
|
+
return false;
|
|
3028
|
+
}
|
|
3029
|
+
const changeSet = state2.changes(changes);
|
|
3030
|
+
dispatch(state2.update({
|
|
3031
|
+
changes: changeSet,
|
|
3032
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3033
|
+
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
3034
|
+
scrollIntoView: true
|
|
3035
|
+
}));
|
|
3036
|
+
return true;
|
|
3037
|
+
};
|
|
3038
|
+
var addBlockquote = setBlockquote(true);
|
|
3039
|
+
var removeBlockquote = setBlockquote(false);
|
|
3040
|
+
var toggleBlockquote = (target) => {
|
|
3041
|
+
return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
|
|
3042
|
+
};
|
|
3043
|
+
var addCodeblock = (target) => {
|
|
3044
|
+
const { state: state2, dispatch } = target;
|
|
3045
|
+
const { selection } = state2;
|
|
3046
|
+
if (selection.ranges.length === 1 && selection.main.empty) {
|
|
3047
|
+
const { head } = selection.main;
|
|
3048
|
+
const line = state2.doc.lineAt(head);
|
|
3049
|
+
if (!/\S/.test(line.text) && head === line.from) {
|
|
3050
|
+
snippets.codeblock(target, null, line.from, line.to);
|
|
3051
|
+
return true;
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
const ranges = [];
|
|
3055
|
+
for (const { from, to } of selection.ranges) {
|
|
3056
|
+
let blockFrom = from;
|
|
3057
|
+
let blockTo = to;
|
|
3058
|
+
syntaxTree(state2).iterate({
|
|
3059
|
+
from,
|
|
3060
|
+
to,
|
|
3061
|
+
enter: (node) => {
|
|
3062
|
+
if (Object.hasOwn(Textblocks, node.name)) {
|
|
3063
|
+
if (from >= node.from && to <= node.to) {
|
|
3064
|
+
blockFrom = node.from;
|
|
3065
|
+
blockTo = node.to;
|
|
3066
|
+
} else {
|
|
3067
|
+
blockFrom = Math.min(blockFrom, state2.doc.lineAt(node.from).from);
|
|
3068
|
+
blockTo = Math.max(blockTo, state2.doc.lineAt(node.to).to);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3352
3071
|
}
|
|
3353
|
-
const num = String(counter2);
|
|
3354
|
-
padding = Math.max(String(max).length, padding);
|
|
3355
|
-
mark2 = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
|
|
3356
|
-
} else {
|
|
3357
|
-
mark2 = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
|
|
3358
|
-
}
|
|
3359
|
-
changes.push({
|
|
3360
|
-
from: nodeFrom,
|
|
3361
|
-
insert: mark2
|
|
3362
3072
|
});
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
from:
|
|
3368
|
-
|
|
3073
|
+
if (ranges.length && ranges[ranges.length - 1].to >= blockFrom - 1) {
|
|
3074
|
+
ranges[ranges.length - 1].to = blockTo;
|
|
3075
|
+
} else {
|
|
3076
|
+
ranges.push({
|
|
3077
|
+
from: blockFrom,
|
|
3078
|
+
to: blockTo
|
|
3369
3079
|
});
|
|
3370
3080
|
}
|
|
3371
3081
|
}
|
|
3372
|
-
if (
|
|
3373
|
-
|
|
3374
|
-
let next = last.node.nextSibling;
|
|
3375
|
-
while (next && /Mark$/.test(next.name)) {
|
|
3376
|
-
next = next.nextSibling;
|
|
3377
|
-
}
|
|
3378
|
-
if (next?.name === "OrderedList") {
|
|
3379
|
-
renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
|
|
3380
|
-
}
|
|
3082
|
+
if (!ranges.length) {
|
|
3083
|
+
return false;
|
|
3381
3084
|
}
|
|
3382
|
-
const
|
|
3085
|
+
const changes = ranges.map(({ from, to }) => {
|
|
3086
|
+
const column = from - state2.doc.lineAt(from).from;
|
|
3087
|
+
return [
|
|
3088
|
+
{
|
|
3089
|
+
from,
|
|
3090
|
+
insert: "```\n" + " ".repeat(column)
|
|
3091
|
+
},
|
|
3092
|
+
{
|
|
3093
|
+
from: to,
|
|
3094
|
+
insert: "\n" + " ".repeat(column) + "```"
|
|
3095
|
+
}
|
|
3096
|
+
];
|
|
3097
|
+
});
|
|
3383
3098
|
dispatch(state2.update({
|
|
3384
|
-
changes
|
|
3385
|
-
|
|
3386
|
-
userEvent: "format.list.add",
|
|
3099
|
+
changes,
|
|
3100
|
+
userEvent: "format.codeblock.add",
|
|
3387
3101
|
scrollIntoView: true
|
|
3388
3102
|
}));
|
|
3389
3103
|
return true;
|
|
3390
3104
|
};
|
|
3391
|
-
var
|
|
3392
|
-
let lastBlock = -1;
|
|
3105
|
+
var removeCodeblock = ({ state: state2, dispatch }) => {
|
|
3393
3106
|
const changes = [];
|
|
3394
|
-
|
|
3395
|
-
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
3107
|
+
let lastBlock = -1;
|
|
3396
3108
|
for (const { from, to } of state2.selection.ranges) {
|
|
3397
|
-
|
|
3109
|
+
syntaxTree(state2).iterate({
|
|
3398
3110
|
from,
|
|
3399
3111
|
to,
|
|
3400
3112
|
enter: (node) => {
|
|
3113
|
+
if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
|
|
3114
|
+
lastBlock = node.from;
|
|
3115
|
+
const firstLine = state2.doc.lineAt(node.from);
|
|
3116
|
+
if (node.name === "FencedCode") {
|
|
3117
|
+
changes.push({
|
|
3118
|
+
from: node.from,
|
|
3119
|
+
to: firstLine.to + 1 + node.from - firstLine.from
|
|
3120
|
+
});
|
|
3121
|
+
const lastLine = state2.doc.lineAt(node.to);
|
|
3122
|
+
if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
|
|
3123
|
+
changes.push({
|
|
3124
|
+
from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
|
|
3125
|
+
to: lastLine.to
|
|
3126
|
+
});
|
|
3127
|
+
}
|
|
3128
|
+
} else {
|
|
3129
|
+
const column = node.from - firstLine.from;
|
|
3130
|
+
for (let line = firstLine; ; line = state2.doc.line(line.number + 1)) {
|
|
3131
|
+
changes.push({
|
|
3132
|
+
from: line.from + column - 4,
|
|
3133
|
+
to: line.from + column
|
|
3134
|
+
});
|
|
3135
|
+
if (line.to >= node.to) {
|
|
3136
|
+
break;
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
});
|
|
3143
|
+
}
|
|
3144
|
+
if (!changes.length) {
|
|
3145
|
+
return false;
|
|
3146
|
+
}
|
|
3147
|
+
dispatch(state2.update({
|
|
3148
|
+
changes,
|
|
3149
|
+
userEvent: "format.codeblock.remove",
|
|
3150
|
+
scrollIntoView: true
|
|
3151
|
+
}));
|
|
3152
|
+
return true;
|
|
3153
|
+
};
|
|
3154
|
+
var toggleCodeblock = (target) => {
|
|
3155
|
+
return (getFormatting(target.state).blockType === "codeblock" ? removeCodeblock : addCodeblock)(target);
|
|
3156
|
+
};
|
|
3157
|
+
var formattingKeymap = (options = {}) => {
|
|
3158
|
+
return [
|
|
3159
|
+
keymap6.of([
|
|
3160
|
+
{
|
|
3161
|
+
key: "meta-b",
|
|
3162
|
+
run: toggleStrong
|
|
3163
|
+
}
|
|
3164
|
+
])
|
|
3165
|
+
];
|
|
3166
|
+
};
|
|
3167
|
+
var InlineMarker = {
|
|
3168
|
+
Emphasis: 1,
|
|
3169
|
+
StrongEmphasis: 0,
|
|
3170
|
+
InlineCode: 3,
|
|
3171
|
+
Strikethrough: 2
|
|
3172
|
+
};
|
|
3173
|
+
var IgnoreInline = /* @__PURE__ */ new Set([
|
|
3174
|
+
"Autolink",
|
|
3175
|
+
"CodeMark",
|
|
3176
|
+
"CodeText",
|
|
3177
|
+
"Comment",
|
|
3178
|
+
"EmphasisMark",
|
|
3179
|
+
"Hardbreak",
|
|
3180
|
+
"HeaderMark",
|
|
3181
|
+
"HTMLTag",
|
|
3182
|
+
"LinkMark",
|
|
3183
|
+
"ListMark",
|
|
3184
|
+
"ProcessingInstruction",
|
|
3185
|
+
"QuoteMark",
|
|
3186
|
+
"StrikethroughMark",
|
|
3187
|
+
"SubscriptMark",
|
|
3188
|
+
"SuperscriptMark",
|
|
3189
|
+
"TaskMarker"
|
|
3190
|
+
]);
|
|
3191
|
+
var Textblocks = {
|
|
3192
|
+
ATXHeading1: "heading1",
|
|
3193
|
+
ATXHeading2: "heading2",
|
|
3194
|
+
ATXHeading3: "heading3",
|
|
3195
|
+
ATXHeading4: "heading4",
|
|
3196
|
+
ATXHeading5: "heading5",
|
|
3197
|
+
ATXHeading6: "heading6",
|
|
3198
|
+
CodeBlock: "codeblock",
|
|
3199
|
+
FencedCode: "codeblock",
|
|
3200
|
+
Paragraph: "paragraph",
|
|
3201
|
+
SetextHeading1: "heading1",
|
|
3202
|
+
SetextHeading2: "heading2",
|
|
3203
|
+
TableCell: "tablecell",
|
|
3204
|
+
Task: "paragraph"
|
|
3205
|
+
};
|
|
3206
|
+
var getFormatting = (state2) => {
|
|
3207
|
+
let blockType = null;
|
|
3208
|
+
const inline = [
|
|
3209
|
+
null,
|
|
3210
|
+
null,
|
|
3211
|
+
null,
|
|
3212
|
+
null
|
|
3213
|
+
];
|
|
3214
|
+
let link = false;
|
|
3215
|
+
let blockQuote = null;
|
|
3216
|
+
let listStyle = null;
|
|
3217
|
+
const stack = [];
|
|
3218
|
+
let currentBlock = null;
|
|
3219
|
+
const advanceInline = (upto) => {
|
|
3220
|
+
if (!currentBlock) {
|
|
3221
|
+
return;
|
|
3222
|
+
}
|
|
3223
|
+
upto = Math.min(upto, currentBlock.end);
|
|
3224
|
+
if (upto <= currentBlock.pos) {
|
|
3225
|
+
return;
|
|
3226
|
+
}
|
|
3227
|
+
for (let i = 0; i < currentBlock.active.length; i++) {
|
|
3228
|
+
if (inline[i] === false) {
|
|
3229
|
+
continue;
|
|
3230
|
+
} else if (currentBlock.active[i]) {
|
|
3231
|
+
inline[i] = true;
|
|
3232
|
+
} else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
|
|
3233
|
+
inline[i] = false;
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
currentBlock.pos = upto;
|
|
3237
|
+
};
|
|
3238
|
+
const skipInline = (upto) => {
|
|
3239
|
+
if (currentBlock && upto > currentBlock.pos) {
|
|
3240
|
+
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
3241
|
+
}
|
|
3242
|
+
};
|
|
3243
|
+
const { selection } = state2;
|
|
3244
|
+
for (const range of selection.ranges) {
|
|
3245
|
+
if (range.empty && inline.some((v) => v === null)) {
|
|
3246
|
+
const contextSize = Math.min(range.head, 6);
|
|
3247
|
+
const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
|
|
3248
|
+
let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
|
|
3249
|
+
for (let i = 0; i < contextSize; i++) {
|
|
3250
|
+
const ch = contextAfter[i];
|
|
3251
|
+
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
3252
|
+
contextAfter = contextAfter.slice(0, i);
|
|
3253
|
+
break;
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
for (let i = 0; i < inline.length; i++) {
|
|
3257
|
+
const mark2 = inlineMarkerText(i);
|
|
3258
|
+
const found = contextAfter.indexOf(mark2);
|
|
3259
|
+
if (found > -1) {
|
|
3260
|
+
contextAfter = contextAfter.slice(0, found) + contextAfter.slice(found + mark2.length);
|
|
3261
|
+
if (inline[i] === null) {
|
|
3262
|
+
inline[i] = true;
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
syntaxTree(state2).iterate({
|
|
3268
|
+
from: range.from,
|
|
3269
|
+
to: range.to,
|
|
3270
|
+
enter: (node) => {
|
|
3271
|
+
advanceInline(node.from);
|
|
3401
3272
|
const { name } = node;
|
|
3402
3273
|
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
3403
3274
|
stack.push(name);
|
|
3404
|
-
} else if (name === "
|
|
3405
|
-
|
|
3275
|
+
} else if (name === "Link") {
|
|
3276
|
+
link = true;
|
|
3277
|
+
} else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {
|
|
3278
|
+
if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
3279
|
+
stack[stack.length - 1] = "TaskList";
|
|
3280
|
+
}
|
|
3281
|
+
const blockCode = Textblocks[name];
|
|
3282
|
+
if (blockType === null) {
|
|
3283
|
+
blockType = blockCode;
|
|
3284
|
+
} else if (blockType !== blockCode) {
|
|
3285
|
+
blockType = false;
|
|
3286
|
+
}
|
|
3287
|
+
if (blockCode !== "codeblock" && inline.some((i) => i !== false)) {
|
|
3288
|
+
currentBlock = {
|
|
3289
|
+
pos: Math.max(range.from, node.from),
|
|
3290
|
+
end: Math.min(range.to, node.to),
|
|
3291
|
+
active: [
|
|
3292
|
+
false,
|
|
3293
|
+
false,
|
|
3294
|
+
false,
|
|
3295
|
+
false
|
|
3296
|
+
]
|
|
3297
|
+
};
|
|
3298
|
+
}
|
|
3299
|
+
} else if (Object.hasOwn(InlineMarker, name) && currentBlock) {
|
|
3300
|
+
const index = InlineMarker[name];
|
|
3301
|
+
if (range.empty && inline[index] === null) {
|
|
3302
|
+
inline[index] = true;
|
|
3303
|
+
}
|
|
3304
|
+
currentBlock.active[index] = true;
|
|
3305
|
+
} else if (IgnoreInline.has(name)) {
|
|
3306
|
+
skipInline(node.to);
|
|
3406
3307
|
}
|
|
3407
3308
|
},
|
|
3408
3309
|
leave: (node) => {
|
|
3310
|
+
advanceInline(node.to);
|
|
3409
3311
|
const { name } = node;
|
|
3410
3312
|
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
3411
3313
|
stack.pop();
|
|
3412
|
-
} else if (
|
|
3413
|
-
|
|
3414
|
-
let
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
changes.push({
|
|
3421
|
-
from: node.from,
|
|
3422
|
-
to: node.from + mark2[0].length
|
|
3423
|
-
});
|
|
3424
|
-
while (line.to < node.to) {
|
|
3425
|
-
line = state2.doc.lineAt(line.to + 1);
|
|
3426
|
-
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
3427
|
-
if (open > column) {
|
|
3428
|
-
changes.push({
|
|
3429
|
-
from: line.from + column,
|
|
3430
|
-
to: line.from + Math.min(column + mark2[0].length, open)
|
|
3431
|
-
});
|
|
3314
|
+
} else if (Object.hasOwn(Textblocks, name)) {
|
|
3315
|
+
let hasList = false;
|
|
3316
|
+
let hasQuote = false;
|
|
3317
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
3318
|
+
if (stack[i] === "Blockquote") {
|
|
3319
|
+
hasQuote = true;
|
|
3320
|
+
} else if (!hasList) {
|
|
3321
|
+
hasList = stack[i] === "TaskList" ? "task" : stack[i] === "BulletList" ? "bullet" : "ordered";
|
|
3432
3322
|
}
|
|
3433
3323
|
}
|
|
3434
|
-
if (
|
|
3435
|
-
|
|
3324
|
+
if (blockQuote === null) {
|
|
3325
|
+
blockQuote = hasQuote;
|
|
3326
|
+
} else if (!hasQuote && blockQuote) {
|
|
3327
|
+
blockQuote = false;
|
|
3436
3328
|
}
|
|
3437
|
-
|
|
3329
|
+
if (listStyle === null) {
|
|
3330
|
+
listStyle = hasList;
|
|
3331
|
+
} else if (listStyle !== hasList) {
|
|
3332
|
+
listStyle = false;
|
|
3333
|
+
}
|
|
3334
|
+
currentBlock = null;
|
|
3335
|
+
} else if (Object.hasOwn(InlineMarker, name) && currentBlock) {
|
|
3336
|
+
currentBlock.active[InlineMarker[name]] = false;
|
|
3438
3337
|
}
|
|
3439
3338
|
}
|
|
3440
3339
|
});
|
|
3441
3340
|
}
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
return (active ? removeList(type) : addList(type))(target);
|
|
3341
|
+
const { from, to } = state2.doc.lineAt(selection.main.anchor);
|
|
3342
|
+
const blankLine = from === to;
|
|
3343
|
+
return {
|
|
3344
|
+
blankLine,
|
|
3345
|
+
blockType: blockType || null,
|
|
3346
|
+
blockQuote: blockQuote ?? false,
|
|
3347
|
+
code: inline[3] ?? false,
|
|
3348
|
+
emphasis: inline[1] ?? false,
|
|
3349
|
+
strong: inline[0] ?? false,
|
|
3350
|
+
strikethrough: inline[2] ?? false,
|
|
3351
|
+
link,
|
|
3352
|
+
listStyle: listStyle || null
|
|
3353
|
+
};
|
|
3456
3354
|
};
|
|
3457
|
-
var
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
from: item.from + Math.max(0, size - newNum.length),
|
|
3468
|
-
to: item.from + size,
|
|
3469
|
-
insert: newNum
|
|
3355
|
+
var useFormattingState = () => {
|
|
3356
|
+
const [state2, setState] = useState();
|
|
3357
|
+
const observer = useMemo(() => EditorView11.updateListener.of((update2) => {
|
|
3358
|
+
if (update2.docChanged || update2.selectionSet) {
|
|
3359
|
+
setState((prevState) => {
|
|
3360
|
+
const newState = getFormatting(update2.state);
|
|
3361
|
+
if (!prevState || !formattingEquals(prevState, newState)) {
|
|
3362
|
+
return newState;
|
|
3363
|
+
}
|
|
3364
|
+
return prevState;
|
|
3470
3365
|
});
|
|
3471
|
-
counter++;
|
|
3472
3366
|
}
|
|
3473
|
-
}
|
|
3367
|
+
}), [
|
|
3368
|
+
setState
|
|
3369
|
+
]);
|
|
3370
|
+
return [
|
|
3371
|
+
state2,
|
|
3372
|
+
observer
|
|
3373
|
+
];
|
|
3474
3374
|
};
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
lines.push(line);
|
|
3518
|
-
}
|
|
3375
|
+
|
|
3376
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/action.ts
|
|
3377
|
+
var processAction = (view, action) => {
|
|
3378
|
+
let inlineType, listType;
|
|
3379
|
+
switch (action.type) {
|
|
3380
|
+
case "heading":
|
|
3381
|
+
setHeading(parseInt(action.data))(view);
|
|
3382
|
+
break;
|
|
3383
|
+
case "strong":
|
|
3384
|
+
case "emphasis":
|
|
3385
|
+
case "strikethrough":
|
|
3386
|
+
case "code":
|
|
3387
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
3388
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
3389
|
+
break;
|
|
3390
|
+
case "list-ordered":
|
|
3391
|
+
case "list-bullet":
|
|
3392
|
+
case "list-task":
|
|
3393
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
3394
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
3395
|
+
break;
|
|
3396
|
+
case "blockquote":
|
|
3397
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
3398
|
+
break;
|
|
3399
|
+
case "codeblock":
|
|
3400
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
3401
|
+
break;
|
|
3402
|
+
case "table":
|
|
3403
|
+
insertTable(view);
|
|
3404
|
+
break;
|
|
3405
|
+
case "link":
|
|
3406
|
+
(action.data === false ? removeLink : addLink())(view);
|
|
3407
|
+
break;
|
|
3408
|
+
case "image":
|
|
3409
|
+
addLink({
|
|
3410
|
+
url: action.data,
|
|
3411
|
+
image: true
|
|
3412
|
+
})(view);
|
|
3413
|
+
break;
|
|
3414
|
+
case "comment":
|
|
3415
|
+
createComment(view);
|
|
3416
|
+
break;
|
|
3519
3417
|
}
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
changes.push({
|
|
3524
|
-
from: line.from,
|
|
3525
|
-
insert: /\S/.test(line.text) ? "> " : ">"
|
|
3526
|
-
});
|
|
3527
|
-
} else {
|
|
3528
|
-
const quote = /((?:[\s>\-+*]|\d+[.)])*?)> ?/.exec(line.text);
|
|
3529
|
-
if (quote) {
|
|
3530
|
-
changes.push({
|
|
3531
|
-
from: line.from + quote[1].length,
|
|
3532
|
-
to: line.from + quote[0].length
|
|
3533
|
-
});
|
|
3534
|
-
}
|
|
3418
|
+
requestAnimationFrame(() => {
|
|
3419
|
+
if (!view.hasFocus) {
|
|
3420
|
+
view.focus();
|
|
3535
3421
|
}
|
|
3536
|
-
}
|
|
3537
|
-
if (!changes.length) {
|
|
3538
|
-
return false;
|
|
3539
|
-
}
|
|
3540
|
-
const changeSet = state2.changes(changes);
|
|
3541
|
-
dispatch(state2.update({
|
|
3542
|
-
changes: changeSet,
|
|
3543
|
-
selection: state2.selection.map(changeSet, 1),
|
|
3544
|
-
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
3545
|
-
scrollIntoView: true
|
|
3546
|
-
}));
|
|
3547
|
-
return true;
|
|
3548
|
-
};
|
|
3549
|
-
var addBlockquote = setBlockquote(true);
|
|
3550
|
-
var removeBlockquote = setBlockquote(false);
|
|
3551
|
-
var toggleBlockquote = (target) => {
|
|
3552
|
-
return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
|
|
3422
|
+
});
|
|
3553
3423
|
};
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
});
|
|
3424
|
+
|
|
3425
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
3426
|
+
import { completionKeymap as completionKeymap2 } from "@codemirror/autocomplete";
|
|
3427
|
+
import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
|
|
3428
|
+
import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
|
|
3429
|
+
import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
3430
|
+
import { languages } from "@codemirror/language-data";
|
|
3431
|
+
import { lintKeymap } from "@codemirror/lint";
|
|
3432
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
3433
|
+
import { keymap as keymap7 } from "@codemirror/view";
|
|
3434
|
+
|
|
3435
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
|
|
3436
|
+
import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
|
|
3437
|
+
import { HighlightStyle } from "@codemirror/language";
|
|
3438
|
+
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
3439
|
+
import { Table } from "@lezer/markdown";
|
|
3440
|
+
var markdownTags = {
|
|
3441
|
+
Blockquote: Tag.define(),
|
|
3442
|
+
CodeMark: Tag.define(),
|
|
3443
|
+
CodeText: Tag.define(),
|
|
3444
|
+
EmphasisMark: Tag.define(),
|
|
3445
|
+
HeaderMark: Tag.define(),
|
|
3446
|
+
InlineCode: Tag.define(),
|
|
3447
|
+
LinkLabel: Tag.define(),
|
|
3448
|
+
LinkReference: Tag.define(),
|
|
3449
|
+
ListMark: Tag.define(),
|
|
3450
|
+
QuoteMark: Tag.define(),
|
|
3451
|
+
URL: Tag.define(),
|
|
3452
|
+
// Custom.
|
|
3453
|
+
TableCell: Tag.define()
|
|
3454
|
+
};
|
|
3455
|
+
Table.defineNodes?.forEach((node) => {
|
|
3456
|
+
switch (node?.name) {
|
|
3457
|
+
case "TableCell": {
|
|
3458
|
+
node.style = markdownTags.TableCell;
|
|
3459
|
+
break;
|
|
3591
3460
|
}
|
|
3592
3461
|
}
|
|
3593
|
-
|
|
3594
|
-
|
|
3462
|
+
});
|
|
3463
|
+
var markdownTagsExtensions = [
|
|
3464
|
+
Table,
|
|
3465
|
+
{
|
|
3466
|
+
props: [
|
|
3467
|
+
styleTags(markdownTags)
|
|
3468
|
+
]
|
|
3595
3469
|
}
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3470
|
+
];
|
|
3471
|
+
var markdownHighlightStyle = (readonly) => {
|
|
3472
|
+
return HighlightStyle.define([
|
|
3473
|
+
{
|
|
3474
|
+
tag: [
|
|
3475
|
+
tags.keyword,
|
|
3476
|
+
tags.name,
|
|
3477
|
+
tags.deleted,
|
|
3478
|
+
tags.character,
|
|
3479
|
+
tags.propertyName,
|
|
3480
|
+
tags.macroName,
|
|
3481
|
+
tags.color,
|
|
3482
|
+
tags.constant(tags.name),
|
|
3483
|
+
tags.standard(tags.name),
|
|
3484
|
+
tags.definition(tags.name),
|
|
3485
|
+
tags.separator,
|
|
3486
|
+
tags.typeName,
|
|
3487
|
+
tags.className,
|
|
3488
|
+
tags.number,
|
|
3489
|
+
tags.changed,
|
|
3490
|
+
tags.annotation,
|
|
3491
|
+
tags.modifier,
|
|
3492
|
+
tags.self,
|
|
3493
|
+
tags.namespace,
|
|
3494
|
+
tags.operator,
|
|
3495
|
+
tags.operatorKeyword,
|
|
3496
|
+
tags.escape,
|
|
3497
|
+
tags.regexp,
|
|
3498
|
+
tags.special(tags.string),
|
|
3499
|
+
tags.meta,
|
|
3500
|
+
tags.comment,
|
|
3501
|
+
tags.atom,
|
|
3502
|
+
tags.bool,
|
|
3503
|
+
tags.special(tags.variableName),
|
|
3504
|
+
tags.processingInstruction,
|
|
3505
|
+
tags.string,
|
|
3506
|
+
tags.inserted,
|
|
3507
|
+
tags.invalid
|
|
3508
|
+
],
|
|
3509
|
+
color: "inherit !important"
|
|
3510
|
+
},
|
|
3511
|
+
// Markdown marks.
|
|
3512
|
+
{
|
|
3513
|
+
tag: [
|
|
3514
|
+
tags.meta,
|
|
3515
|
+
tags.processingInstruction,
|
|
3516
|
+
markdownTags.LinkLabel,
|
|
3517
|
+
markdownTags.LinkReference,
|
|
3518
|
+
markdownTags.ListMark
|
|
3519
|
+
],
|
|
3520
|
+
class: mark
|
|
3521
|
+
},
|
|
3522
|
+
// Markdown marks.
|
|
3523
|
+
{
|
|
3524
|
+
tag: [
|
|
3525
|
+
markdownTags.CodeMark,
|
|
3526
|
+
markdownTags.HeaderMark,
|
|
3527
|
+
markdownTags.QuoteMark,
|
|
3528
|
+
markdownTags.EmphasisMark
|
|
3529
|
+
],
|
|
3530
|
+
class: mark
|
|
3531
|
+
},
|
|
3532
|
+
// E.g., code block language (after ```).
|
|
3533
|
+
{
|
|
3534
|
+
tag: [
|
|
3535
|
+
tags.function(tags.variableName),
|
|
3536
|
+
tags.labelName
|
|
3537
|
+
],
|
|
3538
|
+
class: codeMark
|
|
3539
|
+
},
|
|
3540
|
+
{
|
|
3541
|
+
tag: [
|
|
3542
|
+
tags.monospace
|
|
3543
|
+
],
|
|
3544
|
+
class: "font-mono"
|
|
3545
|
+
},
|
|
3546
|
+
// Headings.
|
|
3547
|
+
{
|
|
3548
|
+
tag: tags.heading1,
|
|
3549
|
+
class: heading(1)
|
|
3550
|
+
},
|
|
3551
|
+
{
|
|
3552
|
+
tag: tags.heading2,
|
|
3553
|
+
class: heading(2)
|
|
3554
|
+
},
|
|
3555
|
+
{
|
|
3556
|
+
tag: tags.heading3,
|
|
3557
|
+
class: heading(3)
|
|
3558
|
+
},
|
|
3559
|
+
{
|
|
3560
|
+
tag: tags.heading4,
|
|
3561
|
+
class: heading(4)
|
|
3562
|
+
},
|
|
3563
|
+
{
|
|
3564
|
+
tag: tags.heading5,
|
|
3565
|
+
class: heading(5)
|
|
3566
|
+
},
|
|
3567
|
+
{
|
|
3568
|
+
tag: tags.heading6,
|
|
3569
|
+
class: heading(6)
|
|
3570
|
+
},
|
|
3571
|
+
// Emphasis.
|
|
3572
|
+
{
|
|
3573
|
+
tag: tags.emphasis,
|
|
3574
|
+
class: italic
|
|
3575
|
+
},
|
|
3576
|
+
{
|
|
3577
|
+
tag: tags.strong,
|
|
3578
|
+
class: bold
|
|
3579
|
+
},
|
|
3580
|
+
{
|
|
3581
|
+
tag: tags.strikethrough,
|
|
3582
|
+
class: strikethrough
|
|
3583
|
+
},
|
|
3584
|
+
// Naked URLs.
|
|
3585
|
+
{
|
|
3586
|
+
tag: [
|
|
3587
|
+
markdownTags.URL
|
|
3588
|
+
],
|
|
3589
|
+
class: inlineUrl
|
|
3590
|
+
},
|
|
3591
|
+
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
3592
|
+
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
3593
|
+
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
3594
|
+
// the code, but all other CSS properties will be inherited.
|
|
3595
|
+
// IMPORTANT: Therefore, the fenced code block will use the base editor font unless changed by an extension.
|
|
3596
|
+
{
|
|
3597
|
+
tag: [
|
|
3598
|
+
markdownTags.CodeText,
|
|
3599
|
+
markdownTags.InlineCode
|
|
3600
|
+
],
|
|
3601
|
+
class: code
|
|
3602
|
+
},
|
|
3603
|
+
{
|
|
3604
|
+
tag: [
|
|
3605
|
+
markdownTags.QuoteMark
|
|
3606
|
+
],
|
|
3607
|
+
class: blockquote
|
|
3608
|
+
},
|
|
3609
|
+
{
|
|
3610
|
+
tag: [
|
|
3611
|
+
markdownTags.TableCell
|
|
3612
|
+
],
|
|
3613
|
+
class: "font-mono"
|
|
3614
|
+
}
|
|
3615
|
+
], {
|
|
3616
|
+
scope: markdownLanguage2,
|
|
3617
|
+
all: {
|
|
3618
|
+
fontFamily: getToken("fontFamily.body", []).join(",")
|
|
3619
|
+
}
|
|
3608
3620
|
});
|
|
3609
|
-
dispatch(state2.update({
|
|
3610
|
-
changes,
|
|
3611
|
-
userEvent: "format.codeblock.add",
|
|
3612
|
-
scrollIntoView: true
|
|
3613
|
-
}));
|
|
3614
|
-
return true;
|
|
3615
3621
|
};
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3622
|
+
|
|
3623
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
|
|
3624
|
+
var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
3625
|
+
return [
|
|
3626
|
+
// Main extension.
|
|
3627
|
+
// https://github.com/codemirror/lang-markdown
|
|
3628
|
+
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
3629
|
+
markdown({
|
|
3630
|
+
// GRM by default (vs strict CommonMark):
|
|
3631
|
+
// Table, TaskList, Strikethrough, and Autolink.
|
|
3632
|
+
// NOTE: This extends the parser; it doesn't affect rendering.
|
|
3633
|
+
// https://github.github.com/gfm
|
|
3634
|
+
// https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
|
|
3635
|
+
base: markdownLanguage3,
|
|
3636
|
+
// Languages for syntax highlighting fenced code blocks.
|
|
3637
|
+
codeLanguages: languages,
|
|
3638
|
+
// Parser extensions.
|
|
3639
|
+
extensions: [
|
|
3640
|
+
// GFM provided by default.
|
|
3641
|
+
markdownTagsExtensions
|
|
3642
|
+
]
|
|
3643
|
+
}),
|
|
3644
|
+
// https://github.com/codemirror/theme-one-dark
|
|
3645
|
+
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
|
|
3646
|
+
// Custom styles.
|
|
3647
|
+
syntaxHighlighting(markdownHighlightStyle()),
|
|
3648
|
+
keymap7.of([
|
|
3649
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
3650
|
+
indentWithTab2,
|
|
3651
|
+
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
3652
|
+
...defaultKeymap2,
|
|
3653
|
+
...completionKeymap2,
|
|
3654
|
+
...lintKeymap
|
|
3655
|
+
])
|
|
3656
|
+
];
|
|
3657
|
+
};
|
|
3658
|
+
|
|
3659
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
3660
|
+
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
3661
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
3662
|
+
import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
3663
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
3664
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
3665
|
+
toDOM() {
|
|
3666
|
+
const el = document.createElement("span");
|
|
3667
|
+
el.className = "cm-hr";
|
|
3668
|
+
return el;
|
|
3669
|
+
}
|
|
3670
|
+
};
|
|
3671
|
+
var LinkButton = class extends WidgetType3 {
|
|
3672
|
+
constructor(url, render) {
|
|
3673
|
+
super();
|
|
3674
|
+
this.url = url;
|
|
3675
|
+
this.render = render;
|
|
3676
|
+
}
|
|
3677
|
+
eq(other) {
|
|
3678
|
+
return this.url === other.url;
|
|
3679
|
+
}
|
|
3680
|
+
toDOM(view) {
|
|
3681
|
+
const el = document.createElement("span");
|
|
3682
|
+
this.render(el, this.url);
|
|
3683
|
+
return el;
|
|
3684
|
+
}
|
|
3685
|
+
};
|
|
3686
|
+
var CheckboxWidget = class extends WidgetType3 {
|
|
3687
|
+
constructor(_checked) {
|
|
3688
|
+
super();
|
|
3689
|
+
this._checked = _checked;
|
|
3690
|
+
}
|
|
3691
|
+
eq(other) {
|
|
3692
|
+
return this._checked === other._checked;
|
|
3693
|
+
}
|
|
3694
|
+
toDOM(view) {
|
|
3695
|
+
const input = document.createElement("input");
|
|
3696
|
+
input.className = "cm-task-checkbox ch-checkbox ch-focus-ring -mbs-0.5";
|
|
3697
|
+
input.type = "checkbox";
|
|
3698
|
+
input.checked = this._checked;
|
|
3699
|
+
if (view.state.readOnly) {
|
|
3700
|
+
input.setAttribute("disabled", "true");
|
|
3701
|
+
} else {
|
|
3702
|
+
input.onmousedown = (event) => {
|
|
3703
|
+
const pos = view.posAtDOM(input);
|
|
3704
|
+
const text = view.state.sliceDoc(pos, pos + 3);
|
|
3705
|
+
if (text === (this._checked ? "[x]" : "[ ]")) {
|
|
3706
|
+
view.dispatch({
|
|
3707
|
+
changes: {
|
|
3708
|
+
from: pos + 1,
|
|
3709
|
+
to: pos + 2,
|
|
3710
|
+
insert: this._checked ? " " : "x"
|
|
3649
3711
|
}
|
|
3650
|
-
}
|
|
3712
|
+
});
|
|
3713
|
+
event.preventDefault();
|
|
3651
3714
|
}
|
|
3652
|
-
}
|
|
3653
|
-
}
|
|
3715
|
+
};
|
|
3716
|
+
}
|
|
3717
|
+
return input;
|
|
3654
3718
|
}
|
|
3655
|
-
|
|
3719
|
+
ignoreEvent() {
|
|
3656
3720
|
return false;
|
|
3657
3721
|
}
|
|
3658
|
-
dispatch(state2.update({
|
|
3659
|
-
changes,
|
|
3660
|
-
userEvent: "format.codeblock.remove",
|
|
3661
|
-
scrollIntoView: true
|
|
3662
|
-
}));
|
|
3663
|
-
return true;
|
|
3664
|
-
};
|
|
3665
|
-
var toggleCodeblock = (target) => {
|
|
3666
|
-
return (getFormatting(target.state).blockType === "codeblock" ? removeCodeblock : addCodeblock)(target);
|
|
3667
|
-
};
|
|
3668
|
-
var formattingKeymap = (options = {}) => {
|
|
3669
|
-
return [
|
|
3670
|
-
keymap6.of([
|
|
3671
|
-
{
|
|
3672
|
-
key: "meta-b",
|
|
3673
|
-
run: toggleStrong
|
|
3674
|
-
}
|
|
3675
|
-
])
|
|
3676
|
-
];
|
|
3677
3722
|
};
|
|
3678
|
-
var
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3723
|
+
var hide = Decoration5.replace({});
|
|
3724
|
+
var fencedCodeLine = Decoration5.line({
|
|
3725
|
+
class: mx2("cm-code cm-codeblock-line")
|
|
3726
|
+
});
|
|
3727
|
+
var fencedCodeLineFirst = Decoration5.line({
|
|
3728
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
|
3729
|
+
});
|
|
3730
|
+
var fencedCodeLineLast = Decoration5.line({
|
|
3731
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
|
3732
|
+
});
|
|
3733
|
+
var horizontalRule = Decoration5.replace({
|
|
3734
|
+
widget: new HorizontalRuleWidget()
|
|
3735
|
+
});
|
|
3736
|
+
var checkedTask = Decoration5.replace({
|
|
3737
|
+
widget: new CheckboxWidget(true)
|
|
3738
|
+
});
|
|
3739
|
+
var uncheckedTask = Decoration5.replace({
|
|
3740
|
+
widget: new CheckboxWidget(false)
|
|
3741
|
+
});
|
|
3742
|
+
var editingRange = (state2, range, focus) => {
|
|
3743
|
+
const { readOnly, selection: { main: { head } } } = state2;
|
|
3744
|
+
return focus && !readOnly && head >= range.from && head <= range.to;
|
|
3683
3745
|
};
|
|
3684
|
-
var
|
|
3685
|
-
"Autolink",
|
|
3746
|
+
var MarksByParent = /* @__PURE__ */ new Set([
|
|
3686
3747
|
"CodeMark",
|
|
3687
|
-
"CodeText",
|
|
3688
|
-
"Comment",
|
|
3689
3748
|
"EmphasisMark",
|
|
3690
|
-
"Hardbreak",
|
|
3691
|
-
"HeaderMark",
|
|
3692
|
-
"HTMLTag",
|
|
3693
|
-
"LinkMark",
|
|
3694
|
-
"ListMark",
|
|
3695
|
-
"ProcessingInstruction",
|
|
3696
|
-
"QuoteMark",
|
|
3697
3749
|
"StrikethroughMark",
|
|
3698
3750
|
"SubscriptMark",
|
|
3699
|
-
"SuperscriptMark"
|
|
3700
|
-
"TaskMarker"
|
|
3751
|
+
"SuperscriptMark"
|
|
3701
3752
|
]);
|
|
3702
|
-
var
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
ATXHeading5: "heading5",
|
|
3708
|
-
ATXHeading6: "heading6",
|
|
3709
|
-
CodeBlock: "codeblock",
|
|
3710
|
-
FencedCode: "codeblock",
|
|
3711
|
-
Paragraph: "paragraph",
|
|
3712
|
-
SetextHeading1: "heading1",
|
|
3713
|
-
SetextHeading2: "heading2",
|
|
3714
|
-
TableCell: "tablecell",
|
|
3715
|
-
Task: "paragraph"
|
|
3716
|
-
};
|
|
3717
|
-
var getFormatting = (state2) => {
|
|
3718
|
-
let blockType = null;
|
|
3719
|
-
const inline = [
|
|
3720
|
-
null,
|
|
3721
|
-
null,
|
|
3722
|
-
null,
|
|
3723
|
-
null
|
|
3724
|
-
];
|
|
3725
|
-
let link = false;
|
|
3726
|
-
let blockQuote = null;
|
|
3727
|
-
let listStyle = null;
|
|
3728
|
-
const stack = [];
|
|
3729
|
-
let currentBlock = null;
|
|
3730
|
-
const advanceInline = (upto) => {
|
|
3731
|
-
if (!currentBlock) {
|
|
3732
|
-
return;
|
|
3733
|
-
}
|
|
3734
|
-
upto = Math.min(upto, currentBlock.end);
|
|
3735
|
-
if (upto <= currentBlock.pos) {
|
|
3736
|
-
return;
|
|
3737
|
-
}
|
|
3738
|
-
for (let i = 0; i < currentBlock.active.length; i++) {
|
|
3739
|
-
if (inline[i] === false) {
|
|
3740
|
-
continue;
|
|
3741
|
-
} else if (currentBlock.active[i]) {
|
|
3742
|
-
inline[i] = true;
|
|
3743
|
-
} else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
|
|
3744
|
-
inline[i] = false;
|
|
3745
|
-
}
|
|
3746
|
-
}
|
|
3747
|
-
currentBlock.pos = upto;
|
|
3748
|
-
};
|
|
3749
|
-
const skipInline = (upto) => {
|
|
3750
|
-
if (currentBlock && upto > currentBlock.pos) {
|
|
3751
|
-
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
3752
|
-
}
|
|
3753
|
-
};
|
|
3754
|
-
const { selection } = state2;
|
|
3755
|
-
for (const range of selection.ranges) {
|
|
3756
|
-
if (range.empty && inline.some((v) => v === null)) {
|
|
3757
|
-
const contextSize = Math.min(range.head, 6);
|
|
3758
|
-
const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
|
|
3759
|
-
let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
|
|
3760
|
-
for (let i = 0; i < contextSize; i++) {
|
|
3761
|
-
const ch = contextAfter[i];
|
|
3762
|
-
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
3763
|
-
contextAfter = contextAfter.slice(0, i);
|
|
3764
|
-
break;
|
|
3765
|
-
}
|
|
3766
|
-
}
|
|
3767
|
-
for (let i = 0; i < inline.length; i++) {
|
|
3768
|
-
const mark2 = inlineMarkerText(i);
|
|
3769
|
-
const found = contextAfter.indexOf(mark2);
|
|
3770
|
-
if (found > -1) {
|
|
3771
|
-
contextAfter = contextAfter.slice(0, found) + contextAfter.slice(found + mark2.length);
|
|
3772
|
-
if (inline[i] === null) {
|
|
3773
|
-
inline[i] = true;
|
|
3774
|
-
}
|
|
3775
|
-
}
|
|
3776
|
-
}
|
|
3777
|
-
}
|
|
3753
|
+
var buildDecorations = (view, options, focus) => {
|
|
3754
|
+
const deco = new RangeSetBuilder2();
|
|
3755
|
+
const atomicDeco = new RangeSetBuilder2();
|
|
3756
|
+
const { state: state2 } = view;
|
|
3757
|
+
for (const { from, to } of view.visibleRanges) {
|
|
3778
3758
|
syntaxTree2(state2).iterate({
|
|
3779
|
-
from
|
|
3780
|
-
to
|
|
3759
|
+
from,
|
|
3760
|
+
to,
|
|
3781
3761
|
enter: (node) => {
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3762
|
+
if (node.name === "FencedCode") {
|
|
3763
|
+
const editing = editingRange(state2, node, focus);
|
|
3764
|
+
for (const block of view.viewportLineBlocks) {
|
|
3765
|
+
if (block.to < node.from) {
|
|
3766
|
+
continue;
|
|
3767
|
+
}
|
|
3768
|
+
if (block.from > node.to) {
|
|
3769
|
+
break;
|
|
3770
|
+
}
|
|
3771
|
+
const first = block.from <= node.from;
|
|
3772
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
|
|
3773
|
+
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
3774
|
+
if (!editing && (first || last)) {
|
|
3775
|
+
atomicDeco.add(block.from, block.to, hide);
|
|
3776
|
+
}
|
|
3797
3777
|
}
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3778
|
+
return false;
|
|
3779
|
+
} else if (node.name === "Link") {
|
|
3780
|
+
const marks = node.node.getChildren("LinkMark");
|
|
3781
|
+
const urlNode = node.node.getChild("URL");
|
|
3782
|
+
const editing = editingRange(state2, node, focus);
|
|
3783
|
+
if (urlNode && marks.length >= 2) {
|
|
3784
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
3785
|
+
if (!editing) {
|
|
3786
|
+
atomicDeco.add(node.from, marks[0].to, hide);
|
|
3787
|
+
}
|
|
3788
|
+
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
3789
|
+
tagName: "a",
|
|
3790
|
+
attributes: {
|
|
3791
|
+
class: "cm-link",
|
|
3792
|
+
href: url,
|
|
3793
|
+
rel: "noreferrer",
|
|
3794
|
+
target: "_blank"
|
|
3795
|
+
}
|
|
3796
|
+
}));
|
|
3797
|
+
if (!editing) {
|
|
3798
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
|
|
3799
|
+
widget: new LinkButton(url, options.renderLinkButton)
|
|
3800
|
+
}) : hide);
|
|
3801
|
+
}
|
|
3809
3802
|
}
|
|
3810
|
-
} else if (
|
|
3811
|
-
const
|
|
3812
|
-
if (
|
|
3813
|
-
|
|
3803
|
+
} else if (node.name === "HeaderMark") {
|
|
3804
|
+
const parent = node.node.parent;
|
|
3805
|
+
if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
|
|
3806
|
+
const next = state2.doc.sliceString(node.to, node.to + 1);
|
|
3807
|
+
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
3814
3808
|
}
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
}
|
|
3819
|
-
},
|
|
3820
|
-
leave: (node) => {
|
|
3821
|
-
advanceInline(node.to);
|
|
3822
|
-
const { name } = node;
|
|
3823
|
-
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
3824
|
-
stack.pop();
|
|
3825
|
-
} else if (Object.hasOwn(Textblocks, name)) {
|
|
3826
|
-
let hasList = false;
|
|
3827
|
-
let hasQuote = false;
|
|
3828
|
-
for (let i = stack.length - 1; i >= 0; i--) {
|
|
3829
|
-
if (stack[i] === "Blockquote") {
|
|
3830
|
-
hasQuote = true;
|
|
3831
|
-
} else if (!hasList) {
|
|
3832
|
-
hasList = stack[i] === "TaskList" ? "task" : stack[i] === "BulletList" ? "bullet" : "ordered";
|
|
3833
|
-
}
|
|
3809
|
+
} else if (node.name === "HorizontalRule") {
|
|
3810
|
+
if (!editingRange(state2, node, focus)) {
|
|
3811
|
+
deco.add(node.from, node.to, horizontalRule);
|
|
3834
3812
|
}
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3813
|
+
} else if (node.name === "TaskMarker") {
|
|
3814
|
+
if (!editingRange(state2, node, focus)) {
|
|
3815
|
+
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
3816
|
+
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
3817
|
+
class: "cm-task"
|
|
3818
|
+
}));
|
|
3819
|
+
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
3839
3820
|
}
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
listStyle = false;
|
|
3821
|
+
} else if (MarksByParent.has(node.name)) {
|
|
3822
|
+
if (!editingRange(state2, node.node.parent, focus)) {
|
|
3823
|
+
atomicDeco.add(node.from, node.to, hide);
|
|
3844
3824
|
}
|
|
3845
|
-
currentBlock = null;
|
|
3846
|
-
} else if (Object.hasOwn(InlineMarker, name) && currentBlock) {
|
|
3847
|
-
currentBlock.active[InlineMarker[name]] = false;
|
|
3848
3825
|
}
|
|
3849
3826
|
}
|
|
3850
3827
|
});
|
|
3851
3828
|
}
|
|
3852
|
-
const { from, to } = state2.doc.lineAt(selection.main.anchor);
|
|
3853
|
-
const blankLine = from === to;
|
|
3854
3829
|
return {
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
blockQuote: blockQuote ?? false,
|
|
3858
|
-
code: inline[3] ?? false,
|
|
3859
|
-
emphasis: inline[1] ?? false,
|
|
3860
|
-
strong: inline[0] ?? false,
|
|
3861
|
-
strikethrough: inline[2] ?? false,
|
|
3862
|
-
link,
|
|
3863
|
-
listStyle: listStyle || null
|
|
3830
|
+
deco: deco.finish(),
|
|
3831
|
+
atomicDeco: atomicDeco.finish()
|
|
3864
3832
|
};
|
|
3865
3833
|
};
|
|
3866
|
-
var
|
|
3867
|
-
|
|
3868
|
-
const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
|
|
3869
|
-
if (update2.docChanged || update2.selectionSet) {
|
|
3870
|
-
const newState = getFormatting(update2.state);
|
|
3871
|
-
if (!state2 || !compareFormatting(state2, newState)) {
|
|
3872
|
-
setState(newState);
|
|
3873
|
-
}
|
|
3874
|
-
}
|
|
3875
|
-
}), []);
|
|
3834
|
+
var forceUpdate = StateEffect4.define();
|
|
3835
|
+
var decorateMarkdown = (options = {}) => {
|
|
3876
3836
|
return [
|
|
3877
|
-
|
|
3878
|
-
|
|
3837
|
+
ViewPlugin4.fromClass(class {
|
|
3838
|
+
constructor(view) {
|
|
3839
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
|
|
3840
|
+
}
|
|
3841
|
+
update(update2) {
|
|
3842
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
|
3843
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
|
|
3844
|
+
this.clearUpdate();
|
|
3845
|
+
} else if (update2.selectionSet) {
|
|
3846
|
+
this.scheduleUpdate(update2.view);
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
// TODO(burdon): BUG: If the cursor is at the end of a link at the end of a line,
|
|
3850
|
+
// the cursor will float in space or be in the wrong position after the decoration is applied.
|
|
3851
|
+
scheduleUpdate(view) {
|
|
3852
|
+
this.clearUpdate();
|
|
3853
|
+
this.pendingUpdate = setTimeout(() => {
|
|
3854
|
+
view.dispatch({
|
|
3855
|
+
effects: forceUpdate.of(null)
|
|
3856
|
+
});
|
|
3857
|
+
}, options.selectionChangeDelay);
|
|
3858
|
+
}
|
|
3859
|
+
clearUpdate() {
|
|
3860
|
+
if (this.pendingUpdate) {
|
|
3861
|
+
clearTimeout(this.pendingUpdate);
|
|
3862
|
+
this.pendingUpdate = void 0;
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
destroy() {
|
|
3866
|
+
this.clearUpdate();
|
|
3867
|
+
}
|
|
3868
|
+
}, {
|
|
3869
|
+
provide: (plugin) => [
|
|
3870
|
+
EditorView12.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
3871
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration5.none),
|
|
3872
|
+
EditorView12.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration5.none)
|
|
3873
|
+
]
|
|
3874
|
+
}),
|
|
3875
|
+
formattingStyles
|
|
3879
3876
|
];
|
|
3880
3877
|
};
|
|
3878
|
+
var formattingStyles = EditorView12.baseTheme({
|
|
3879
|
+
"& .cm-code": {
|
|
3880
|
+
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
3881
|
+
},
|
|
3882
|
+
"& .cm-codeblock-line": {
|
|
3883
|
+
paddingInline: "1rem !important"
|
|
3884
|
+
},
|
|
3885
|
+
"& .cm-codeblock-end": {
|
|
3886
|
+
display: "inline-block",
|
|
3887
|
+
width: "100%",
|
|
3888
|
+
position: "relative",
|
|
3889
|
+
"&::after": {
|
|
3890
|
+
position: "absolute",
|
|
3891
|
+
inset: 0,
|
|
3892
|
+
content: '""'
|
|
3893
|
+
}
|
|
3894
|
+
},
|
|
3895
|
+
"& .cm-codeblock-first": {
|
|
3896
|
+
borderTopLeftRadius: ".5rem",
|
|
3897
|
+
borderTopRightRadius: ".5rem"
|
|
3898
|
+
},
|
|
3899
|
+
"& .cm-codeblock-last": {
|
|
3900
|
+
borderBottomLeftRadius: ".5rem",
|
|
3901
|
+
borderBottomRightRadius: ".5rem"
|
|
3902
|
+
},
|
|
3903
|
+
"&light .cm-codeblock-line, &light .cm-activeLine.cm-codeblock-line": {
|
|
3904
|
+
background: getToken("extend.semanticColors.input.light"),
|
|
3905
|
+
mixBlendMode: "darken"
|
|
3906
|
+
},
|
|
3907
|
+
"&dark .cm-codeblock-line, &dark .cm-activeLine.cm-codeblock-line": {
|
|
3908
|
+
background: getToken("extend.semanticColors.input.dark"),
|
|
3909
|
+
mixBlendMode: "lighten"
|
|
3910
|
+
},
|
|
3911
|
+
"& .cm-hr": {
|
|
3912
|
+
display: "inline-block",
|
|
3913
|
+
width: "100%",
|
|
3914
|
+
height: "0",
|
|
3915
|
+
verticalAlign: "middle",
|
|
3916
|
+
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
3917
|
+
},
|
|
3918
|
+
"& .cm-task": {
|
|
3919
|
+
color: getToken("extend.colors.blue.500")
|
|
3920
|
+
},
|
|
3921
|
+
"& .cm-task-checkbox": {
|
|
3922
|
+
marginLeft: "4px",
|
|
3923
|
+
marginRight: "4px"
|
|
3924
|
+
}
|
|
3925
|
+
});
|
|
3881
3926
|
|
|
3882
3927
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3883
3928
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3884
3929
|
import { StateField as StateField5 } from "@codemirror/state";
|
|
3885
|
-
import { Decoration as Decoration6, EditorView as
|
|
3930
|
+
import { Decoration as Decoration6, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3886
3931
|
var image = (options = {}) => {
|
|
3887
3932
|
return StateField5.define({
|
|
3888
3933
|
create: (state2) => {
|
|
@@ -3909,7 +3954,7 @@ var image = (options = {}) => {
|
|
|
3909
3954
|
add: buildDecorations2(from, to, tr.state)
|
|
3910
3955
|
});
|
|
3911
3956
|
},
|
|
3912
|
-
provide: (field) =>
|
|
3957
|
+
provide: (field) => EditorView13.decorations.from(field)
|
|
3913
3958
|
});
|
|
3914
3959
|
};
|
|
3915
3960
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3959,6 +4004,8 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
3959
4004
|
return img;
|
|
3960
4005
|
}
|
|
3961
4006
|
};
|
|
4007
|
+
var imageUpload = (options = {}) => {
|
|
4008
|
+
};
|
|
3962
4009
|
|
|
3963
4010
|
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
3964
4011
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
@@ -3997,12 +4044,12 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
|
3997
4044
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3998
4045
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3999
4046
|
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "@codemirror/state";
|
|
4000
|
-
import { Decoration as Decoration7, EditorView as
|
|
4047
|
+
import { Decoration as Decoration7, EditorView as EditorView14, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
4001
4048
|
var table = (options = {}) => {
|
|
4002
4049
|
return StateField6.define({
|
|
4003
4050
|
create: (state2) => update(state2, options),
|
|
4004
4051
|
update: (_, tr) => update(tr.state, options),
|
|
4005
|
-
provide: (field) =>
|
|
4052
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
4006
4053
|
});
|
|
4007
4054
|
};
|
|
4008
4055
|
var update = (state2, options) => {
|
|
@@ -4096,8 +4143,8 @@ var TableWidget = class extends WidgetType5 {
|
|
|
4096
4143
|
|
|
4097
4144
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
4098
4145
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
4099
|
-
import { log as
|
|
4100
|
-
var
|
|
4146
|
+
import { log as log6 } from "@dxos/log";
|
|
4147
|
+
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
|
|
4101
4148
|
var mention = ({ onSearch }) => {
|
|
4102
4149
|
return autocompletion2({
|
|
4103
4150
|
// TODO(burdon): Not working.
|
|
@@ -4109,10 +4156,10 @@ var mention = ({ onSearch }) => {
|
|
|
4109
4156
|
icons: false,
|
|
4110
4157
|
override: [
|
|
4111
4158
|
(context) => {
|
|
4112
|
-
|
|
4159
|
+
log6.info("completion context", {
|
|
4113
4160
|
context
|
|
4114
4161
|
}, {
|
|
4115
|
-
F:
|
|
4162
|
+
F: __dxlog_file8,
|
|
4116
4163
|
L: 26,
|
|
4117
4164
|
S: void 0,
|
|
4118
4165
|
C: (f, a) => f(...a)
|
|
@@ -4134,21 +4181,30 @@ var mention = ({ onSearch }) => {
|
|
|
4134
4181
|
|
|
4135
4182
|
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
|
4136
4183
|
import { Facet as Facet6 } from "@codemirror/state";
|
|
4137
|
-
import { keymap as
|
|
4184
|
+
import { keymap as keymap8 } from "@codemirror/view";
|
|
4138
4185
|
import { vim } from "@replit/codemirror-vim";
|
|
4186
|
+
import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
|
|
4139
4187
|
var focusEvent = "focus.container";
|
|
4140
4188
|
var editorMode = Facet6.define({
|
|
4141
4189
|
combine: (modes) => modes[0] ?? {}
|
|
4142
4190
|
});
|
|
4143
4191
|
var EditorModes = {
|
|
4144
4192
|
default: [],
|
|
4193
|
+
vscode: [
|
|
4194
|
+
// https://github.com/replit/codemirror-vscode-keymap
|
|
4195
|
+
editorMode.of({
|
|
4196
|
+
type: "vscode"
|
|
4197
|
+
}),
|
|
4198
|
+
keymap8.of(vscodeKeymap)
|
|
4199
|
+
],
|
|
4145
4200
|
vim: [
|
|
4201
|
+
// https://github.com/replit/codemirror-vim
|
|
4146
4202
|
vim(),
|
|
4147
4203
|
editorMode.of({
|
|
4148
4204
|
type: "vim",
|
|
4149
4205
|
noTabster: true
|
|
4150
4206
|
}),
|
|
4151
|
-
|
|
4207
|
+
keymap8.of([
|
|
4152
4208
|
{
|
|
4153
4209
|
key: "Alt-Escape",
|
|
4154
4210
|
run: (view) => {
|
|
@@ -4163,18 +4219,18 @@ var EditorModes = {
|
|
|
4163
4219
|
};
|
|
4164
4220
|
|
|
4165
4221
|
// packages/ui/react-ui-editor/src/extensions/state.ts
|
|
4166
|
-
import { Transaction
|
|
4167
|
-
import { EditorView as
|
|
4222
|
+
import { Transaction } from "@codemirror/state";
|
|
4223
|
+
import { EditorView as EditorView15, keymap as keymap9 } from "@codemirror/view";
|
|
4168
4224
|
import { debounce as debounce2 } from "@dxos/async";
|
|
4169
4225
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
4170
4226
|
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
4171
|
-
var
|
|
4227
|
+
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/state.ts";
|
|
4172
4228
|
var scrollAnnotation = "dxos.org/cm/scrolling";
|
|
4173
4229
|
var keyPrefix = "dxos.org/react-ui-editor/state";
|
|
4174
4230
|
var localStorageStateStoreAdapter = {
|
|
4175
4231
|
setState: (id, state2) => {
|
|
4176
4232
|
invariant4(id, void 0, {
|
|
4177
|
-
F:
|
|
4233
|
+
F: __dxlog_file9,
|
|
4178
4234
|
L: 35,
|
|
4179
4235
|
S: void 0,
|
|
4180
4236
|
A: [
|
|
@@ -4186,7 +4242,7 @@ var localStorageStateStoreAdapter = {
|
|
|
4186
4242
|
},
|
|
4187
4243
|
getState: (id) => {
|
|
4188
4244
|
invariant4(id, void 0, {
|
|
4189
|
-
F:
|
|
4245
|
+
F: __dxlog_file9,
|
|
4190
4246
|
L: 39,
|
|
4191
4247
|
S: void 0,
|
|
4192
4248
|
A: [
|
|
@@ -4202,7 +4258,7 @@ var state = ({ getState, setState } = {}) => {
|
|
|
4202
4258
|
const setStateDebounced = debounce2(setState, 1e3);
|
|
4203
4259
|
return [
|
|
4204
4260
|
// TODO(burdon): Track scrolling (currently only updates when cursor moves).
|
|
4205
|
-
|
|
4261
|
+
EditorView15.updateListener.of(({ view, changes, transactions }) => {
|
|
4206
4262
|
const id = view.state.facet(documentId2);
|
|
4207
4263
|
if (!id || transactions.some((tr) => tr.isUserEvent(scrollAnnotation))) {
|
|
4208
4264
|
return;
|
|
@@ -4228,18 +4284,18 @@ var state = ({ getState, setState } = {}) => {
|
|
|
4228
4284
|
}
|
|
4229
4285
|
}
|
|
4230
4286
|
}),
|
|
4231
|
-
getState &&
|
|
4287
|
+
getState && keymap9.of([
|
|
4232
4288
|
{
|
|
4233
4289
|
key: "ctrl-r",
|
|
4234
4290
|
run: (view) => {
|
|
4235
4291
|
const state2 = getState(view.state.facet(documentId2));
|
|
4236
4292
|
if (state2) {
|
|
4237
4293
|
view.dispatch({
|
|
4238
|
-
effects:
|
|
4294
|
+
effects: EditorView15.scrollIntoView(state2.scrollTo.from, {
|
|
4239
4295
|
yMargin: 0
|
|
4240
4296
|
}),
|
|
4241
4297
|
selection: state2.selection,
|
|
4242
|
-
annotations:
|
|
4298
|
+
annotations: Transaction.userEvent.of(scrollAnnotation)
|
|
4243
4299
|
});
|
|
4244
4300
|
}
|
|
4245
4301
|
return true;
|
|
@@ -4250,7 +4306,7 @@ var state = ({ getState, setState } = {}) => {
|
|
|
4250
4306
|
};
|
|
4251
4307
|
|
|
4252
4308
|
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
|
4253
|
-
import { keymap as
|
|
4309
|
+
import { keymap as keymap10 } from "@codemirror/view";
|
|
4254
4310
|
var defaultItems = [
|
|
4255
4311
|
"hello world!",
|
|
4256
4312
|
"this is a test.",
|
|
@@ -4260,7 +4316,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4260
4316
|
let t;
|
|
4261
4317
|
let idx = 0;
|
|
4262
4318
|
return [
|
|
4263
|
-
|
|
4319
|
+
keymap10.of([
|
|
4264
4320
|
{
|
|
4265
4321
|
// Reset.
|
|
4266
4322
|
key: "alt-meta-'",
|
|
@@ -4307,9 +4363,9 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4307
4363
|
};
|
|
4308
4364
|
|
|
4309
4365
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4310
|
-
var
|
|
4366
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4311
4367
|
var instanceCount = 0;
|
|
4312
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo =
|
|
4368
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo = EditorView16.scrollIntoView(0, {
|
|
4313
4369
|
yMargin: 0
|
|
4314
4370
|
}), moveToEndOfLine, debug, dataTestId }, forwardedRef) => {
|
|
4315
4371
|
const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
|
|
@@ -4330,11 +4386,11 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4330
4386
|
autoFocus
|
|
4331
4387
|
]);
|
|
4332
4388
|
useEffect2(() => {
|
|
4333
|
-
|
|
4389
|
+
log7("create", {
|
|
4334
4390
|
id,
|
|
4335
4391
|
instanceId
|
|
4336
4392
|
}, {
|
|
4337
|
-
F:
|
|
4393
|
+
F: __dxlog_file10,
|
|
4338
4394
|
L: 88,
|
|
4339
4395
|
S: void 0,
|
|
4340
4396
|
C: (f, a) => f(...a)
|
|
@@ -4345,16 +4401,16 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4345
4401
|
extensions: [
|
|
4346
4402
|
id && documentId2.of(id),
|
|
4347
4403
|
// TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
F:
|
|
4404
|
+
EditorView16.exceptionSink.of((err) => {
|
|
4405
|
+
log7.catch(err, void 0, {
|
|
4406
|
+
F: __dxlog_file10,
|
|
4351
4407
|
L: 101,
|
|
4352
4408
|
S: void 0,
|
|
4353
4409
|
C: (f, a) => f(...a)
|
|
4354
4410
|
});
|
|
4355
4411
|
}),
|
|
4356
4412
|
// Focus.
|
|
4357
|
-
|
|
4413
|
+
EditorView16.updateListener.of((update2) => {
|
|
4358
4414
|
update2.transactions.forEach((transaction) => {
|
|
4359
4415
|
if (transaction.isUserEvent(focusEvent)) {
|
|
4360
4416
|
rootRef.current?.focus();
|
|
@@ -4364,7 +4420,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4364
4420
|
extensions
|
|
4365
4421
|
].filter(isNotFalsy4)
|
|
4366
4422
|
});
|
|
4367
|
-
const view2 = new
|
|
4423
|
+
const view2 = new EditorView16({
|
|
4368
4424
|
state: state2,
|
|
4369
4425
|
parent: rootRef.current,
|
|
4370
4426
|
scrollTo,
|
|
@@ -4390,8 +4446,16 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4390
4446
|
}
|
|
4391
4447
|
setView(view2);
|
|
4392
4448
|
return () => {
|
|
4449
|
+
log7("destroy", {
|
|
4450
|
+
id,
|
|
4451
|
+
instanceId
|
|
4452
|
+
}, {
|
|
4453
|
+
F: __dxlog_file10,
|
|
4454
|
+
L: 150,
|
|
4455
|
+
S: void 0,
|
|
4456
|
+
C: (f, a) => f(...a)
|
|
4457
|
+
});
|
|
4393
4458
|
view2?.destroy();
|
|
4394
|
-
setView(null);
|
|
4395
4459
|
};
|
|
4396
4460
|
}, [
|
|
4397
4461
|
doc,
|
|
@@ -4421,9 +4485,10 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4421
4485
|
});
|
|
4422
4486
|
|
|
4423
4487
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4424
|
-
import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic
|
|
4488
|
+
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic } from "@phosphor-icons/react";
|
|
4425
4489
|
import { createContext } from "@radix-ui/react-context";
|
|
4426
|
-
import React2, { useRef as useRef2, useState as useState3 } from "react";
|
|
4490
|
+
import React2, { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
4491
|
+
import { useDropzone } from "react-dropzone";
|
|
4427
4492
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4428
4493
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4429
4494
|
var tooltipProps = {
|
|
@@ -4457,7 +4522,7 @@ var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
|
4457
4522
|
};
|
|
4458
4523
|
var buttonStyles = "min-bs-0 p-2";
|
|
4459
4524
|
var iconStyles = getSize(5);
|
|
4460
|
-
var
|
|
4525
|
+
var ToolbarToggleButton = ({ Icon, children, ...props }) => {
|
|
4461
4526
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4462
4527
|
asChild: true
|
|
4463
4528
|
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
@@ -4470,6 +4535,19 @@ var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
|
4470
4535
|
className: "sr-only"
|
|
4471
4536
|
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4472
4537
|
};
|
|
4538
|
+
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
4539
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4540
|
+
asChild: true
|
|
4541
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
4542
|
+
variant: "ghost",
|
|
4543
|
+
...props,
|
|
4544
|
+
classNames: buttonStyles
|
|
4545
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
4546
|
+
className: iconStyles
|
|
4547
|
+
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4548
|
+
className: "sr-only"
|
|
4549
|
+
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4550
|
+
};
|
|
4473
4551
|
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4474
4552
|
role: "separator",
|
|
4475
4553
|
className: "grow"
|
|
@@ -4580,7 +4658,7 @@ var MarkdownStyles = () => {
|
|
|
4580
4658
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4581
4659
|
type: "multiple",
|
|
4582
4660
|
value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
|
|
4583
|
-
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4661
|
+
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4584
4662
|
key: type,
|
|
4585
4663
|
value: type,
|
|
4586
4664
|
Icon,
|
|
@@ -4614,7 +4692,7 @@ var MarkdownLists = () => {
|
|
|
4614
4692
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4615
4693
|
type: "single",
|
|
4616
4694
|
value: state2?.listStyle ? `list-${state2.listStyle}` : ""
|
|
4617
|
-
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4695
|
+
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4618
4696
|
key: type,
|
|
4619
4697
|
value: type,
|
|
4620
4698
|
Icon,
|
|
@@ -4649,7 +4727,7 @@ var MarkdownBlocks = () => {
|
|
|
4649
4727
|
return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
|
|
4650
4728
|
type: "single",
|
|
4651
4729
|
value: value?.type ?? ""
|
|
4652
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(
|
|
4730
|
+
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
|
|
4653
4731
|
key: type,
|
|
4654
4732
|
value: type,
|
|
4655
4733
|
Icon,
|
|
@@ -4661,78 +4739,73 @@ var MarkdownBlocks = () => {
|
|
|
4661
4739
|
}, t(`${type} label`))));
|
|
4662
4740
|
};
|
|
4663
4741
|
var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(MarkdownHeading, null), /* @__PURE__ */ React2.createElement(MarkdownStyles, null), /* @__PURE__ */ React2.createElement(MarkdownLists, null), /* @__PURE__ */ React2.createElement(MarkdownBlocks, null));
|
|
4664
|
-
var
|
|
4742
|
+
var MarkdownCustom = ({ onUpload } = {}) => {
|
|
4665
4743
|
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4666
4744
|
const { t } = useTranslation(translationKey);
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4745
|
+
const { acceptedFiles, getInputProps, open } = useDropzone({
|
|
4746
|
+
multiple: false,
|
|
4747
|
+
noDrag: true,
|
|
4748
|
+
accept: {
|
|
4749
|
+
"image/*": [
|
|
4750
|
+
".jpg",
|
|
4751
|
+
".jpeg",
|
|
4752
|
+
".png",
|
|
4753
|
+
".gif"
|
|
4754
|
+
]
|
|
4755
|
+
}
|
|
4756
|
+
});
|
|
4757
|
+
useEffect3(() => {
|
|
4758
|
+
if (onUpload && acceptedFiles.length) {
|
|
4759
|
+
requestAnimationFrame(async () => {
|
|
4760
|
+
const f = acceptedFiles[0];
|
|
4761
|
+
const file = new File([
|
|
4762
|
+
f
|
|
4763
|
+
], f.name, {
|
|
4764
|
+
type: f.type,
|
|
4765
|
+
lastModified: f.lastModified
|
|
4766
|
+
});
|
|
4767
|
+
const { url } = await onUpload(file);
|
|
4768
|
+
if (url) {
|
|
4769
|
+
onAction?.({
|
|
4770
|
+
type: "image",
|
|
4771
|
+
data: url
|
|
4772
|
+
});
|
|
4773
|
+
}
|
|
4774
|
+
});
|
|
4775
|
+
}
|
|
4776
|
+
}, [
|
|
4777
|
+
acceptedFiles
|
|
4778
|
+
]);
|
|
4779
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("input", getInputProps()), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4780
|
+
value: "image",
|
|
4781
|
+
Icon: Image,
|
|
4782
|
+
onClick: () => open()
|
|
4783
|
+
}, t("image label")));
|
|
4784
|
+
};
|
|
4785
|
+
var MarkdownActions = () => {
|
|
4786
|
+
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4787
|
+
const { t } = useTranslation(translationKey);
|
|
4788
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4789
|
+
value: "comment",
|
|
4790
|
+
Icon: ChatText,
|
|
4671
4791
|
"data-testid": "editor.toolbar.comment",
|
|
4672
4792
|
onClick: () => onAction?.({
|
|
4673
4793
|
type: "comment"
|
|
4674
|
-
})
|
|
4675
|
-
|
|
4676
|
-
}, /* @__PURE__ */ React2.createElement(ChatText, {
|
|
4677
|
-
className: iconStyles
|
|
4678
|
-
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4679
|
-
className: "sr-only"
|
|
4680
|
-
}, t("comment label")))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("comment label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4794
|
+
})
|
|
4795
|
+
}, t("comment label")));
|
|
4681
4796
|
};
|
|
4682
4797
|
var Toolbar = {
|
|
4683
4798
|
Root: ToolbarRoot,
|
|
4684
|
-
Button:
|
|
4799
|
+
Button: ToolbarToggleButton,
|
|
4685
4800
|
Separator: ToolbarSeparator,
|
|
4686
4801
|
Markdown: MarkdownStandard,
|
|
4687
|
-
|
|
4802
|
+
Custom: MarkdownCustom,
|
|
4803
|
+
Actions: MarkdownActions
|
|
4688
4804
|
};
|
|
4689
4805
|
|
|
4690
4806
|
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
|
4691
4807
|
var useActionHandler = (view) => {
|
|
4692
|
-
return (action) =>
|
|
4693
|
-
if (!view) {
|
|
4694
|
-
return;
|
|
4695
|
-
}
|
|
4696
|
-
let inlineType, listType;
|
|
4697
|
-
switch (action.type) {
|
|
4698
|
-
case "heading":
|
|
4699
|
-
setHeading(parseInt(action.data))(view);
|
|
4700
|
-
break;
|
|
4701
|
-
case "strong":
|
|
4702
|
-
case "emphasis":
|
|
4703
|
-
case "strikethrough":
|
|
4704
|
-
case "code":
|
|
4705
|
-
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4706
|
-
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
4707
|
-
break;
|
|
4708
|
-
case "list-ordered":
|
|
4709
|
-
case "list-bullet":
|
|
4710
|
-
case "list-task":
|
|
4711
|
-
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4712
|
-
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4713
|
-
break;
|
|
4714
|
-
case "blockquote":
|
|
4715
|
-
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
4716
|
-
break;
|
|
4717
|
-
case "codeblock":
|
|
4718
|
-
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
4719
|
-
break;
|
|
4720
|
-
case "table":
|
|
4721
|
-
insertTable(view);
|
|
4722
|
-
break;
|
|
4723
|
-
case "link":
|
|
4724
|
-
(action.data === false ? removeLink : addLink)(view);
|
|
4725
|
-
break;
|
|
4726
|
-
case "comment":
|
|
4727
|
-
createComment(view);
|
|
4728
|
-
break;
|
|
4729
|
-
}
|
|
4730
|
-
setTimeout(() => {
|
|
4731
|
-
if (!view.hasFocus) {
|
|
4732
|
-
view.focus();
|
|
4733
|
-
}
|
|
4734
|
-
});
|
|
4735
|
-
};
|
|
4808
|
+
return (action) => view && processAction(view, action);
|
|
4736
4809
|
};
|
|
4737
4810
|
|
|
4738
4811
|
// packages/ui/react-ui-editor/src/hooks/useDocAccessor.ts
|
|
@@ -4750,40 +4823,48 @@ var useDocAccessor = (text) => {
|
|
|
4750
4823
|
|
|
4751
4824
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4752
4825
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4753
|
-
import { EditorView as
|
|
4754
|
-
import { useEffect as
|
|
4755
|
-
import { log as
|
|
4826
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
4827
|
+
import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
4828
|
+
import { log as log8 } from "@dxos/log";
|
|
4756
4829
|
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4757
|
-
var
|
|
4830
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4758
4831
|
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4759
4832
|
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4760
4833
|
const onUpdate = useRef3();
|
|
4761
4834
|
const [view, setView] = useState4();
|
|
4762
4835
|
const parentRef = useRef3(null);
|
|
4763
|
-
|
|
4836
|
+
useEffect4(() => {
|
|
4764
4837
|
let view2;
|
|
4765
4838
|
if (parentRef.current) {
|
|
4839
|
+
log8("create", {
|
|
4840
|
+
id
|
|
4841
|
+
}, {
|
|
4842
|
+
F: __dxlog_file11,
|
|
4843
|
+
L: 36,
|
|
4844
|
+
S: void 0,
|
|
4845
|
+
C: (f, a) => f(...a)
|
|
4846
|
+
});
|
|
4766
4847
|
const state2 = EditorState3.create({
|
|
4767
4848
|
doc,
|
|
4768
4849
|
selection,
|
|
4769
4850
|
extensions: [
|
|
4770
4851
|
id && documentId2.of(id),
|
|
4771
4852
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
F:
|
|
4775
|
-
L:
|
|
4853
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4854
|
+
log8.catch(err, void 0, {
|
|
4855
|
+
F: __dxlog_file11,
|
|
4856
|
+
L: 46,
|
|
4776
4857
|
S: void 0,
|
|
4777
4858
|
C: (f, a) => f(...a)
|
|
4778
4859
|
});
|
|
4779
4860
|
}),
|
|
4780
4861
|
extensions,
|
|
4781
|
-
|
|
4862
|
+
EditorView17.updateListener.of(() => {
|
|
4782
4863
|
onUpdate.current?.();
|
|
4783
4864
|
})
|
|
4784
4865
|
].filter(isNotFalsy5)
|
|
4785
4866
|
});
|
|
4786
|
-
view2 = new
|
|
4867
|
+
view2 = new EditorView17({
|
|
4787
4868
|
parent: parentRef.current,
|
|
4788
4869
|
scrollTo,
|
|
4789
4870
|
state: state2,
|
|
@@ -4799,10 +4880,18 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
|
4799
4880
|
setView(view2);
|
|
4800
4881
|
}
|
|
4801
4882
|
return () => {
|
|
4883
|
+
log8("destroy", {
|
|
4884
|
+
id
|
|
4885
|
+
}, {
|
|
4886
|
+
F: __dxlog_file11,
|
|
4887
|
+
L: 74,
|
|
4888
|
+
S: void 0,
|
|
4889
|
+
C: (f, a) => f(...a)
|
|
4890
|
+
});
|
|
4802
4891
|
view2?.destroy();
|
|
4803
4892
|
};
|
|
4804
4893
|
}, deps);
|
|
4805
|
-
|
|
4894
|
+
useEffect4(() => {
|
|
4806
4895
|
if (view) {
|
|
4807
4896
|
if (!selection && !view.state.selection.main.anchor) {
|
|
4808
4897
|
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
@@ -4861,30 +4950,30 @@ export {
|
|
|
4861
4950
|
callbackWrapper,
|
|
4862
4951
|
command,
|
|
4863
4952
|
comments,
|
|
4864
|
-
compareFormatting,
|
|
4865
4953
|
createBasicExtensions,
|
|
4866
4954
|
createComment,
|
|
4867
4955
|
createDataExtensions,
|
|
4868
4956
|
createMarkdownExtensions,
|
|
4869
4957
|
createThemeExtensions,
|
|
4870
|
-
cursorLineMargin,
|
|
4871
4958
|
decorateMarkdown,
|
|
4872
4959
|
defaultOptions,
|
|
4873
4960
|
defaultTheme,
|
|
4874
|
-
dnd,
|
|
4875
4961
|
documentId2 as documentId,
|
|
4962
|
+
dropFile,
|
|
4876
4963
|
editorFillLayoutEditor,
|
|
4877
4964
|
editorFillLayoutRoot,
|
|
4878
4965
|
editorMode,
|
|
4879
4966
|
editorWithToolbarLayout,
|
|
4880
4967
|
focusComment,
|
|
4881
4968
|
focusEvent,
|
|
4969
|
+
formattingEquals,
|
|
4882
4970
|
formattingKeymap,
|
|
4883
4971
|
getFormatting,
|
|
4884
4972
|
getToken,
|
|
4885
4973
|
image,
|
|
4974
|
+
imageUpload,
|
|
4886
4975
|
insertTable,
|
|
4887
|
-
|
|
4976
|
+
keymap11 as keymap,
|
|
4888
4977
|
linkTooltip,
|
|
4889
4978
|
listener,
|
|
4890
4979
|
localStorageStateStoreAdapter,
|
|
@@ -4893,6 +4982,7 @@ export {
|
|
|
4893
4982
|
markdownTags,
|
|
4894
4983
|
markdownTagsExtensions,
|
|
4895
4984
|
mention,
|
|
4985
|
+
processAction,
|
|
4896
4986
|
removeBlockquote,
|
|
4897
4987
|
removeCodeblock,
|
|
4898
4988
|
removeLink,
|