@dxos/react-ui-editor 0.3.11-main.69484a6 → 0.3.11-main.69d4f1c
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 +1183 -168
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +8 -4
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +5 -3
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +5 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +54 -10
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.test.d.ts +3 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextModel.d.ts +12 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +2 -2
- package/src/components/TextEditor/TextEditor.tsx +3 -4
- package/src/components/TextEditor/hooks.stories.tsx +6 -1
- package/src/components/Toolbar/Toolbar.stories.tsx +15 -3
- package/src/components/Toolbar/Toolbar.tsx +108 -29
- package/src/extensions/awareness.ts +4 -1
- package/src/extensions/blast.ts +4 -1
- package/src/extensions/comments.ts +14 -4
- package/src/extensions/markdown/formatting.test.ts +481 -0
- package/src/extensions/markdown/formatting.ts +1080 -70
- package/src/extensions/markdown/link.ts +8 -2
- package/src/hooks/useActionHandler.ts +47 -16
- package/src/hooks/useTextModel.ts +17 -1
- package/src/index.ts +1 -1
- package/src/themes/default.ts +7 -4
- package/dist/types/src/components/TextEditor/comments.stories.d.ts +0 -26
- package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +0 -1
- package/src/components/TextEditor/comments.stories.tsx +0 -357
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
// packages/ui/react-ui-editor/src/index.ts
|
|
2
2
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
3
3
|
import { Doc, YText, YXmlFragment } from "@dxos/text-model";
|
|
4
|
+
import { keymap as keymap7 } from "@codemirror/view";
|
|
4
5
|
|
|
5
6
|
// packages/ui/react-ui-editor/src/components/TextEditor/index.ts
|
|
6
7
|
import { tags as tags2 } from "@lezer/highlight";
|
|
7
8
|
|
|
8
9
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
9
10
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
10
|
-
import { EditorView as
|
|
11
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
11
12
|
import { vim } from "@replit/codemirror-vim";
|
|
12
13
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
13
|
-
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState } from "react";
|
|
14
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
|
|
14
15
|
import { log as log2 } from "@dxos/log";
|
|
15
16
|
import { useThemeContext } from "@dxos/react-ui";
|
|
16
|
-
import {
|
|
17
|
+
import { focusRing, mx as mx3 } from "@dxos/react-ui-theme";
|
|
17
18
|
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
18
19
|
|
|
19
20
|
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
|
@@ -782,7 +783,7 @@ var Blaster = class {
|
|
|
782
783
|
initialize() {
|
|
783
784
|
invariant(!this._canvas && !this._ctx, void 0, {
|
|
784
785
|
F: __dxlog_file,
|
|
785
|
-
L:
|
|
786
|
+
L: 141,
|
|
786
787
|
S: this,
|
|
787
788
|
A: [
|
|
788
789
|
"!this._canvas && !this._ctx",
|
|
@@ -819,7 +820,7 @@ var Blaster = class {
|
|
|
819
820
|
start() {
|
|
820
821
|
invariant(this._canvas && this._ctx, void 0, {
|
|
821
822
|
F: __dxlog_file,
|
|
822
|
-
L:
|
|
823
|
+
L: 180,
|
|
823
824
|
S: this,
|
|
824
825
|
A: [
|
|
825
826
|
"this._canvas && this._ctx",
|
|
@@ -1073,11 +1074,25 @@ var logChanges = (trs) => {
|
|
|
1073
1074
|
|
|
1074
1075
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
|
1075
1076
|
var styles2 = EditorView5.baseTheme({
|
|
1076
|
-
"& .cm-comment": {
|
|
1077
|
+
"&light .cm-comment, &light .cm-comment-current": {
|
|
1078
|
+
mixBlendMode: "darken"
|
|
1079
|
+
},
|
|
1080
|
+
"&dark .cm-comment, &dark .cm-comment-current": {
|
|
1081
|
+
mixBlendMode: "plus-lighter"
|
|
1082
|
+
},
|
|
1083
|
+
"&light .cm-comment": {
|
|
1077
1084
|
backgroundColor: getToken("extend.colors.yellow.50")
|
|
1078
1085
|
},
|
|
1079
|
-
"& .cm-comment-current": {
|
|
1086
|
+
"&light .cm-comment-current": {
|
|
1080
1087
|
backgroundColor: getToken("extend.colors.yellow.100")
|
|
1088
|
+
},
|
|
1089
|
+
"&dark .cm-comment": {
|
|
1090
|
+
color: getToken("extend.colors.yellow.50"),
|
|
1091
|
+
backgroundColor: getToken("extend.colors.yellow.900")
|
|
1092
|
+
},
|
|
1093
|
+
"&dark .cm-comment-current": {
|
|
1094
|
+
color: getToken("extend.colors.yellow.100"),
|
|
1095
|
+
backgroundColor: getToken("extend.colors.yellow.950")
|
|
1081
1096
|
}
|
|
1082
1097
|
});
|
|
1083
1098
|
var commentMark = Decoration2.mark({
|
|
@@ -1286,7 +1301,11 @@ var createComment = (view) => {
|
|
|
1286
1301
|
to
|
|
1287
1302
|
});
|
|
1288
1303
|
if (cursor) {
|
|
1289
|
-
const id = options.onCreate?.(
|
|
1304
|
+
const id = options.onCreate?.({
|
|
1305
|
+
cursor,
|
|
1306
|
+
from,
|
|
1307
|
+
location: view.coordsAtPos(from)
|
|
1308
|
+
});
|
|
1290
1309
|
if (id) {
|
|
1291
1310
|
view.dispatch({
|
|
1292
1311
|
effects: setSelection.of({
|
|
@@ -1814,57 +1833,283 @@ var code2 = () => {
|
|
|
1814
1833
|
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1815
1834
|
import { snippet } from "@codemirror/autocomplete";
|
|
1816
1835
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
1817
|
-
import { RangeSetBuilder as RangeSetBuilder2 } from "@codemirror/state";
|
|
1818
|
-
import { Decoration as Decoration4, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1819
|
-
|
|
1820
|
-
|
|
1836
|
+
import { RangeSetBuilder as RangeSetBuilder2, EditorSelection } from "@codemirror/state";
|
|
1837
|
+
import { Decoration as Decoration4, EditorView as EditorView9, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1838
|
+
import { useState, useMemo } from "react";
|
|
1839
|
+
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;
|
|
1840
|
+
var Inline;
|
|
1841
|
+
(function(Inline2) {
|
|
1842
|
+
Inline2[Inline2["Strong"] = 0] = "Strong";
|
|
1843
|
+
Inline2[Inline2["Emphasis"] = 1] = "Emphasis";
|
|
1844
|
+
Inline2[Inline2["Strikethrough"] = 2] = "Strikethrough";
|
|
1845
|
+
Inline2[Inline2["Code"] = 3] = "Code";
|
|
1846
|
+
})(Inline || (Inline = {}));
|
|
1847
|
+
var List;
|
|
1848
|
+
(function(List2) {
|
|
1849
|
+
List2[List2["Ordered"] = 0] = "Ordered";
|
|
1850
|
+
List2[List2["Bullet"] = 1] = "Bullet";
|
|
1851
|
+
List2[List2["Task"] = 2] = "Task";
|
|
1852
|
+
})(List || (List = {}));
|
|
1853
|
+
var setHeading = (level) => ({ state, dispatch }) => {
|
|
1854
|
+
const { selection: { ranges }, doc } = state;
|
|
1821
1855
|
const changes = [];
|
|
1856
|
+
let prevBlock = -1;
|
|
1822
1857
|
for (const range of ranges) {
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
from
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1858
|
+
syntaxTree2(state).iterate({
|
|
1859
|
+
from: range.from,
|
|
1860
|
+
to: range.to,
|
|
1861
|
+
enter: (node) => {
|
|
1862
|
+
if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
prevBlock = node.from;
|
|
1866
|
+
const blockType = Textblocks[node.name];
|
|
1867
|
+
const isHeading = /heading(\d)/.exec(blockType);
|
|
1868
|
+
const curLevel = isHeading ? +isHeading[1] : node.name === "Paragraph" ? 0 : -1;
|
|
1869
|
+
if (curLevel < 0 || curLevel === level) {
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1872
|
+
if (curLevel === 0) {
|
|
1873
|
+
changes.push({
|
|
1874
|
+
from: node.from,
|
|
1875
|
+
insert: "#".repeat(level) + " "
|
|
1876
|
+
});
|
|
1877
|
+
} else if (node.name === "SetextHeading1" || node.name === "SetextHeading2") {
|
|
1878
|
+
const nextLine = doc.lineAt(node.to);
|
|
1879
|
+
if (level) {
|
|
1880
|
+
changes.push({
|
|
1881
|
+
from: node.from,
|
|
1882
|
+
insert: "#".repeat(level) + " "
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
changes.push({
|
|
1886
|
+
from: nextLine.from - 1,
|
|
1887
|
+
to: nextLine.to
|
|
1888
|
+
});
|
|
1889
|
+
} else {
|
|
1890
|
+
if (level === 0) {
|
|
1891
|
+
changes.push({
|
|
1892
|
+
from: node.from,
|
|
1893
|
+
to: Math.min(node.to, node.from + curLevel + 1)
|
|
1894
|
+
});
|
|
1895
|
+
} else if (level < curLevel) {
|
|
1896
|
+
changes.push({
|
|
1897
|
+
from: node.from,
|
|
1898
|
+
to: node.from + (curLevel - level)
|
|
1899
|
+
});
|
|
1900
|
+
} else {
|
|
1901
|
+
changes.push({
|
|
1902
|
+
from: node.from,
|
|
1903
|
+
insert: "#".repeat(level - curLevel)
|
|
1904
|
+
});
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1839
1908
|
});
|
|
1840
1909
|
}
|
|
1910
|
+
if (!changes.length) {
|
|
1911
|
+
return false;
|
|
1912
|
+
}
|
|
1913
|
+
dispatch(state.update({
|
|
1914
|
+
changes,
|
|
1915
|
+
userEvent: "format.setHeading",
|
|
1916
|
+
scrollIntoView: true
|
|
1917
|
+
}));
|
|
1841
1918
|
return true;
|
|
1842
1919
|
};
|
|
1843
|
-
var
|
|
1844
|
-
const
|
|
1845
|
-
|
|
1846
|
-
if (
|
|
1847
|
-
|
|
1920
|
+
var setStyle = (type, enable) => ({ state, dispatch }) => {
|
|
1921
|
+
const marker = inlineMarkerText(type);
|
|
1922
|
+
const changes = state.changeByRange((range) => {
|
|
1923
|
+
if (!enable && range.empty) {
|
|
1924
|
+
const after = state.doc.sliceString(range.head, range.head + 6);
|
|
1925
|
+
const found = after.indexOf(marker);
|
|
1926
|
+
if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
|
|
1927
|
+
const before = state.doc.sliceString(range.head - 6, range.head);
|
|
1928
|
+
if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
|
|
1929
|
+
...before.slice(before.length - found)
|
|
1930
|
+
].reverse().join("") === after.slice(0, found)) {
|
|
1931
|
+
return {
|
|
1932
|
+
changes: [
|
|
1933
|
+
{
|
|
1934
|
+
from: range.head - marker.length - found,
|
|
1935
|
+
to: range.head - found
|
|
1936
|
+
},
|
|
1937
|
+
{
|
|
1938
|
+
from: range.head + found,
|
|
1939
|
+
to: range.head + found + marker.length
|
|
1940
|
+
}
|
|
1941
|
+
],
|
|
1942
|
+
range: EditorSelection.cursor(range.from - marker.length)
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1848
1946
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1947
|
+
const changes2 = [];
|
|
1948
|
+
const changesAtEnd = [];
|
|
1949
|
+
let blockStart = -1;
|
|
1950
|
+
let blockEnd = -1;
|
|
1951
|
+
let startCovered = false;
|
|
1952
|
+
let endCovered = false;
|
|
1953
|
+
let { from, to } = range;
|
|
1954
|
+
syntaxTree2(state).iterate({
|
|
1955
|
+
from,
|
|
1956
|
+
to,
|
|
1957
|
+
enter: (node) => {
|
|
1958
|
+
const { name } = node;
|
|
1959
|
+
if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
|
|
1960
|
+
blockStart = blockContentStart(node);
|
|
1961
|
+
blockEnd = blockContentEnd(node, state.doc);
|
|
1962
|
+
startCovered = endCovered = false;
|
|
1963
|
+
} else if (name === "Link" || name === "Image" && enable) {
|
|
1964
|
+
if (from < node.from && to > node.from && to <= node.to) {
|
|
1965
|
+
to = node.to;
|
|
1966
|
+
} else if (to > node.to && from >= node.from && from < node.to) {
|
|
1967
|
+
from = node.from;
|
|
1968
|
+
}
|
|
1969
|
+
} else if (IgnoreInline.has(name) && enable) {
|
|
1970
|
+
if (node.from < from && node.to > from) {
|
|
1971
|
+
if (to === from) {
|
|
1972
|
+
to = node.to;
|
|
1973
|
+
}
|
|
1974
|
+
from = node.to;
|
|
1975
|
+
}
|
|
1976
|
+
if (node.from < to && node.to > to) {
|
|
1977
|
+
to = node.from;
|
|
1978
|
+
}
|
|
1979
|
+
} else if (Object.hasOwn(InlineMarker, name)) {
|
|
1980
|
+
const markType = InlineMarker[name];
|
|
1981
|
+
const size = inlineMarkerText(markType).length;
|
|
1982
|
+
const openEnd = node.from + size;
|
|
1983
|
+
const closeStart = node.to - size;
|
|
1984
|
+
if (markType === type) {
|
|
1985
|
+
if (openEnd <= from && closeStart >= from) {
|
|
1986
|
+
startCovered = openEnd === from ? "adjacent" : true;
|
|
1987
|
+
}
|
|
1988
|
+
if (openEnd <= to && closeStart >= to) {
|
|
1989
|
+
endCovered = closeStart === to ? "adjacent" : true;
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
if (markType === type || type === 3 && enable) {
|
|
1993
|
+
if (node.from >= from && openEnd <= to) {
|
|
1994
|
+
changes2.push({
|
|
1995
|
+
from: node.from,
|
|
1996
|
+
to: openEnd
|
|
1997
|
+
});
|
|
1998
|
+
if (markType !== type && closeStart >= to) {
|
|
1999
|
+
changesAtEnd.push({
|
|
2000
|
+
from: skipSpaces(Math.min(to, blockEnd), state.doc, 1, blockEnd),
|
|
2001
|
+
insert: inlineMarkerText(markType)
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
if (closeStart >= from && node.to <= to) {
|
|
2006
|
+
changes2.push({
|
|
2007
|
+
from: closeStart,
|
|
2008
|
+
to: node.to
|
|
2009
|
+
});
|
|
2010
|
+
if (markType !== type && openEnd <= from) {
|
|
2011
|
+
changes2.push({
|
|
2012
|
+
from: skipSpaces(Math.max(from, blockStart), state.doc, -1, blockStart),
|
|
2013
|
+
insert: inlineMarkerText(markType)
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
1858
2018
|
}
|
|
1859
|
-
|
|
2019
|
+
},
|
|
2020
|
+
leave: (node) => {
|
|
2021
|
+
if (Object.hasOwn(Textblocks, node.name) && Textblocks[node.name] !== "codeblock") {
|
|
2022
|
+
const rangeStart = Math.max(from, blockStart);
|
|
2023
|
+
const rangeEnd = Math.min(to, blockEnd);
|
|
2024
|
+
if (enable) {
|
|
2025
|
+
if (!startCovered) {
|
|
2026
|
+
changes2.push({
|
|
2027
|
+
from: rangeStart,
|
|
2028
|
+
insert: marker
|
|
2029
|
+
});
|
|
2030
|
+
}
|
|
2031
|
+
if (!endCovered) {
|
|
2032
|
+
changes2.push({
|
|
2033
|
+
from: rangeEnd,
|
|
2034
|
+
insert: marker
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
} else {
|
|
2038
|
+
if (startCovered === "adjacent") {
|
|
2039
|
+
changes2.push({
|
|
2040
|
+
from: from - marker.length,
|
|
2041
|
+
to: from
|
|
2042
|
+
});
|
|
2043
|
+
} else if (startCovered) {
|
|
2044
|
+
changes2.push({
|
|
2045
|
+
from: skipSpaces(rangeStart, state.doc, -1, blockStart),
|
|
2046
|
+
insert: marker
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
2049
|
+
if (endCovered === "adjacent") {
|
|
2050
|
+
changes2.push({
|
|
2051
|
+
from: to,
|
|
2052
|
+
to: to + marker.length
|
|
2053
|
+
});
|
|
2054
|
+
} else if (endCovered) {
|
|
2055
|
+
changes2.push({
|
|
2056
|
+
from: skipSpaces(rangeEnd, state.doc, 1, blockEnd),
|
|
2057
|
+
insert: marker
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
1860
2063
|
});
|
|
1861
|
-
|
|
2064
|
+
const changeSet = state.changes(changes2.concat(changesAtEnd));
|
|
2065
|
+
return {
|
|
2066
|
+
changes: changeSet,
|
|
2067
|
+
range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
|
|
2068
|
+
};
|
|
2069
|
+
});
|
|
2070
|
+
dispatch(state.update(changes, {
|
|
2071
|
+
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
2072
|
+
scrollIntoView: true
|
|
2073
|
+
}));
|
|
1862
2074
|
return true;
|
|
1863
2075
|
};
|
|
2076
|
+
var addStyle = (style) => setStyle(style, true);
|
|
2077
|
+
var removeStyle = (style) => setStyle(style, false);
|
|
2078
|
+
var toggleStyle = (style) => (arg) => {
|
|
2079
|
+
const form = getFormatting(arg.state);
|
|
2080
|
+
return setStyle(style, style === 0 ? !form.strong : style === 1 ? !form.emphasis : style === 2 ? !form.strikethrough : !form.code)(arg);
|
|
2081
|
+
};
|
|
2082
|
+
var toggleStrong = toggleStyle(0);
|
|
2083
|
+
var toggleEmphasis = toggleStyle(1);
|
|
2084
|
+
var toggleStrikethrough = toggleStyle(2);
|
|
2085
|
+
var toggleInlineCode = toggleStyle(3);
|
|
2086
|
+
var inlineMarkerText = (type) => type === 0 ? "**" : type === 2 ? "~~" : type === 1 ? "*" : "`";
|
|
2087
|
+
var blockContentStart = (node) => {
|
|
2088
|
+
const atx = /^ATXHeading(\d)/.exec(node.name);
|
|
2089
|
+
if (atx) {
|
|
2090
|
+
return Math.min(node.to, node.from + +atx[1] + 1);
|
|
2091
|
+
}
|
|
2092
|
+
return node.from;
|
|
2093
|
+
};
|
|
2094
|
+
var blockContentEnd = (node, doc) => {
|
|
2095
|
+
const setext = /^SetextHeading(\d)/.exec(node.name);
|
|
2096
|
+
const lastLine = doc.lineAt(node.to);
|
|
2097
|
+
if (setext || /^[\s>]*$/.exec(lastLine.text)) {
|
|
2098
|
+
return lastLine.from - 1;
|
|
2099
|
+
}
|
|
2100
|
+
return node.to;
|
|
2101
|
+
};
|
|
2102
|
+
var skipSpaces = (pos, doc, dir, limit) => {
|
|
2103
|
+
const line = doc.lineAt(pos);
|
|
2104
|
+
while (pos !== limit && line.text[pos - line.from - (dir < 0 ? 1 : 0)] === " ") {
|
|
2105
|
+
pos += dir;
|
|
2106
|
+
}
|
|
2107
|
+
return pos;
|
|
2108
|
+
};
|
|
1864
2109
|
var snippets = {
|
|
1865
2110
|
codeblock: snippet([
|
|
1866
2111
|
"```#{lang}",
|
|
1867
|
-
"
|
|
2112
|
+
"#{}",
|
|
1868
2113
|
"```"
|
|
1869
2114
|
].join("\n")),
|
|
1870
2115
|
table: snippet([
|
|
@@ -1874,29 +2119,533 @@ var snippets = {
|
|
|
1874
2119
|
"| #{val3} | #{val4} |"
|
|
1875
2120
|
].join("\n"))
|
|
1876
2121
|
};
|
|
1877
|
-
var insertCodeblock = (view) => {
|
|
1878
|
-
const { selection: { main }, doc } = view.state;
|
|
1879
|
-
const { number } = doc.lineAt(main.anchor);
|
|
1880
|
-
const { from } = doc.line(number);
|
|
1881
|
-
snippets.codeblock(view, null, from, from);
|
|
1882
|
-
};
|
|
1883
2122
|
var insertTable = (view) => {
|
|
1884
2123
|
const { selection: { main }, doc } = view.state;
|
|
1885
2124
|
const { number } = doc.lineAt(main.anchor);
|
|
1886
2125
|
const { from } = doc.line(number);
|
|
1887
2126
|
snippets.table(view, null, from, from);
|
|
1888
2127
|
};
|
|
1889
|
-
var
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
2128
|
+
var removeLinkInner = (from, to, changes, state) => {
|
|
2129
|
+
syntaxTree2(state).iterate({
|
|
2130
|
+
from,
|
|
2131
|
+
to,
|
|
2132
|
+
enter: (node) => {
|
|
2133
|
+
if (node.name === "Link" && node.from < to && node.to > from) {
|
|
2134
|
+
node.node.cursor().iterate((node2) => {
|
|
2135
|
+
const { name } = node2;
|
|
2136
|
+
if (name === "LinkMark" || name === "LinkLabel") {
|
|
2137
|
+
changes.push({
|
|
2138
|
+
from: node2.from,
|
|
2139
|
+
to: node2.to
|
|
2140
|
+
});
|
|
2141
|
+
} else if (name === "LinkTitle" || name === "URL") {
|
|
2142
|
+
changes.push({
|
|
2143
|
+
from: skipSpaces(node2.from, state.doc, -1),
|
|
2144
|
+
to: skipSpaces(node2.to, state.doc, 1)
|
|
2145
|
+
});
|
|
2146
|
+
}
|
|
2147
|
+
});
|
|
2148
|
+
return false;
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
});
|
|
2152
|
+
};
|
|
2153
|
+
var removeLink = ({ state, dispatch }) => {
|
|
2154
|
+
const changes = [];
|
|
2155
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2156
|
+
removeLinkInner(from, to, changes, state);
|
|
2157
|
+
}
|
|
2158
|
+
if (!changes) {
|
|
2159
|
+
return false;
|
|
2160
|
+
}
|
|
2161
|
+
dispatch(state.update({
|
|
2162
|
+
changes,
|
|
2163
|
+
userEvent: "format.link.remove",
|
|
2164
|
+
scrollIntoView: true
|
|
2165
|
+
}));
|
|
2166
|
+
return true;
|
|
2167
|
+
};
|
|
2168
|
+
var addLink = ({ state, dispatch }) => {
|
|
2169
|
+
const changes = state.changeByRange((range) => {
|
|
2170
|
+
let { from, to } = range;
|
|
2171
|
+
const cutStyles = [];
|
|
2172
|
+
let okay = null;
|
|
2173
|
+
syntaxTree2(state).iterate({
|
|
2174
|
+
from,
|
|
2175
|
+
to,
|
|
2176
|
+
enter: (node) => {
|
|
2177
|
+
if (Object.hasOwn(Textblocks, node.name)) {
|
|
2178
|
+
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state.doc);
|
|
2179
|
+
} else if (Object.hasOwn(InlineMarker, node.name)) {
|
|
2180
|
+
const sNode = node.node;
|
|
2181
|
+
if (node.from < from && node.to <= to) {
|
|
2182
|
+
if (sNode.firstChild.to === from) {
|
|
2183
|
+
from = node.from;
|
|
2184
|
+
} else {
|
|
2185
|
+
cutStyles.push(sNode);
|
|
2186
|
+
}
|
|
2187
|
+
} else if (node.from >= from && node.to > to) {
|
|
2188
|
+
if (sNode.lastChild.from === to) {
|
|
2189
|
+
to = node.to;
|
|
2190
|
+
} else {
|
|
2191
|
+
cutStyles.push(sNode);
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
});
|
|
2197
|
+
if (okay === null) {
|
|
2198
|
+
const line = state.doc.lineAt(from);
|
|
2199
|
+
okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
|
|
2200
|
+
}
|
|
2201
|
+
if (!okay) {
|
|
2202
|
+
return {
|
|
2203
|
+
range
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
const changes2 = [];
|
|
2207
|
+
const changesAfter = [];
|
|
2208
|
+
removeLinkInner(from, to, changesAfter, state);
|
|
2209
|
+
let cursorOffset = 1;
|
|
2210
|
+
for (const style of cutStyles) {
|
|
2211
|
+
const type = InlineMarker[style.name];
|
|
2212
|
+
const mark2 = inlineMarkerText(type);
|
|
2213
|
+
if (style.from < from) {
|
|
2214
|
+
changes2.push({
|
|
2215
|
+
from: skipSpaces(from, state.doc, -1),
|
|
2216
|
+
insert: mark2
|
|
2217
|
+
});
|
|
2218
|
+
changesAfter.push({
|
|
2219
|
+
from: skipSpaces(from, state.doc, 1, to),
|
|
2220
|
+
insert: mark2
|
|
2221
|
+
});
|
|
2222
|
+
} else {
|
|
2223
|
+
changes2.push({
|
|
2224
|
+
from: skipSpaces(to, state.doc, -1, from),
|
|
2225
|
+
insert: mark2
|
|
2226
|
+
});
|
|
2227
|
+
const after = skipSpaces(to, state.doc, 1);
|
|
2228
|
+
if (after === to) {
|
|
2229
|
+
cursorOffset += mark2.length;
|
|
2230
|
+
}
|
|
2231
|
+
changesAfter.push({
|
|
2232
|
+
from: after,
|
|
2233
|
+
insert: mark2
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
changes2.push({
|
|
2238
|
+
from,
|
|
2239
|
+
insert: "["
|
|
2240
|
+
}, {
|
|
2241
|
+
from: to,
|
|
2242
|
+
insert: "]()"
|
|
2243
|
+
});
|
|
2244
|
+
const changeSet = state.changes(changes2.concat(changesAfter));
|
|
2245
|
+
return {
|
|
2246
|
+
changes: changeSet,
|
|
2247
|
+
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
|
|
2248
|
+
};
|
|
2249
|
+
});
|
|
2250
|
+
if (changes.changes.empty) {
|
|
2251
|
+
return false;
|
|
2252
|
+
}
|
|
2253
|
+
dispatch(state.update(changes, {
|
|
2254
|
+
userEvent: "format.link.add",
|
|
2255
|
+
scrollIntoView: true
|
|
2256
|
+
}));
|
|
2257
|
+
return true;
|
|
2258
|
+
};
|
|
2259
|
+
var addList = (type) => ({ state, dispatch }) => {
|
|
2260
|
+
let lastBlock = -1;
|
|
2261
|
+
let counter = 1;
|
|
2262
|
+
let first = true;
|
|
2263
|
+
let parentColumn = null;
|
|
2264
|
+
const blocks = [];
|
|
2265
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2266
|
+
syntaxTree2(state).iterate({
|
|
2267
|
+
from,
|
|
2268
|
+
to,
|
|
2269
|
+
enter: (node) => {
|
|
2270
|
+
if (Object.hasOwn(Textblocks, node.name) && node.name !== "TableCell" || node.name === "Table") {
|
|
2271
|
+
if (first) {
|
|
2272
|
+
let before = node.node.prevSibling;
|
|
2273
|
+
while (before && /Mark$/.test(before.name)) {
|
|
2274
|
+
before = before.prevSibling;
|
|
2275
|
+
}
|
|
2276
|
+
if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
|
|
2277
|
+
const item = before.lastChild;
|
|
2278
|
+
const itemLine = state.doc.lineAt(item.from);
|
|
2279
|
+
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
2280
|
+
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
2281
|
+
if (type === 0) {
|
|
2282
|
+
const mark2 = /^\s*(\d+)[.)]/.exec(itemText);
|
|
2283
|
+
if (mark2) {
|
|
2284
|
+
parentColumn += mark2[1].length;
|
|
2285
|
+
counter = +mark2[1] + 1;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
first = false;
|
|
2290
|
+
}
|
|
2291
|
+
if (node.from === lastBlock) {
|
|
2292
|
+
return;
|
|
2293
|
+
}
|
|
2294
|
+
lastBlock = node.from;
|
|
2295
|
+
blocks.push({
|
|
2296
|
+
node: node.node,
|
|
2297
|
+
counter,
|
|
2298
|
+
parentColumn
|
|
2299
|
+
});
|
|
2300
|
+
counter++;
|
|
2301
|
+
return false;
|
|
2302
|
+
}
|
|
2303
|
+
},
|
|
2304
|
+
leave: (node) => {
|
|
2305
|
+
if (node.name === "BulletList" || node.name === "OrderedList" || node.name === "Blockquote") {
|
|
2306
|
+
counter = 1;
|
|
2307
|
+
parentColumn = null;
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
});
|
|
2311
|
+
}
|
|
2312
|
+
if (!blocks.length) {
|
|
2313
|
+
return false;
|
|
2314
|
+
}
|
|
2315
|
+
const changes = [];
|
|
2316
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
2317
|
+
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
2318
|
+
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
2319
|
+
let padding = nodeFrom > 0 && !/\s/.test(state.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
2320
|
+
if (type === 0) {
|
|
2321
|
+
padding += String(counter2).length;
|
|
2322
|
+
}
|
|
2323
|
+
let line = state.doc.lineAt(nodeFrom);
|
|
2324
|
+
const column = nodeFrom - line.from;
|
|
2325
|
+
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
2326
|
+
padding = Math.max(padding, parentColumn2 - column);
|
|
2327
|
+
}
|
|
2328
|
+
let mark2;
|
|
2329
|
+
if (type === 0) {
|
|
2330
|
+
let max = counter2;
|
|
2331
|
+
for (let j = i + 1; j < blocks.length; j++) {
|
|
2332
|
+
if (blocks[j].counter !== max + 1) {
|
|
2333
|
+
break;
|
|
2334
|
+
}
|
|
2335
|
+
max++;
|
|
2336
|
+
}
|
|
2337
|
+
const num = String(counter2);
|
|
2338
|
+
padding = Math.max(String(max).length, padding);
|
|
2339
|
+
mark2 = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
|
|
2340
|
+
} else {
|
|
2341
|
+
mark2 = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
|
|
2342
|
+
}
|
|
2343
|
+
changes.push({
|
|
2344
|
+
from: nodeFrom,
|
|
2345
|
+
insert: mark2
|
|
2346
|
+
});
|
|
2347
|
+
while (line.to < node.to) {
|
|
2348
|
+
line = state.doc.lineAt(line.to + 1);
|
|
2349
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2350
|
+
changes.push({
|
|
2351
|
+
from: line.from + Math.min(open, column),
|
|
2352
|
+
insert: " ".repeat(mark2.length)
|
|
2353
|
+
});
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
if (type === 0) {
|
|
2357
|
+
const last = blocks[blocks.length - 1];
|
|
2358
|
+
let next = last.node.nextSibling;
|
|
2359
|
+
while (next && /Mark$/.test(next.name)) {
|
|
2360
|
+
next = next.nextSibling;
|
|
2361
|
+
}
|
|
2362
|
+
if (next?.name === "OrderedList") {
|
|
2363
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state.doc);
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
dispatch(state.update({
|
|
2367
|
+
changes,
|
|
2368
|
+
userEvent: "format.list.add",
|
|
2369
|
+
scrollIntoView: true
|
|
2370
|
+
}));
|
|
2371
|
+
return true;
|
|
2372
|
+
};
|
|
2373
|
+
var removeList = (type) => ({ state, dispatch }) => {
|
|
2374
|
+
let lastBlock = -1;
|
|
2375
|
+
const changes = [];
|
|
2376
|
+
const stack = [];
|
|
2377
|
+
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
2378
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2379
|
+
syntaxTree2(state).iterate({
|
|
2380
|
+
from,
|
|
2381
|
+
to,
|
|
2382
|
+
enter: (node) => {
|
|
2383
|
+
const { name } = node;
|
|
2384
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2385
|
+
stack.push(name);
|
|
2386
|
+
} else if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
2387
|
+
stack[stack.length - 1] = "TaskList";
|
|
2388
|
+
}
|
|
2389
|
+
},
|
|
2390
|
+
leave: (node) => {
|
|
2391
|
+
const { name } = node;
|
|
2392
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2393
|
+
stack.pop();
|
|
2394
|
+
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
2395
|
+
lastBlock = node.from;
|
|
2396
|
+
let line = state.doc.lineAt(node.from);
|
|
2397
|
+
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
2398
|
+
if (!mark2) {
|
|
2399
|
+
return false;
|
|
2400
|
+
}
|
|
2401
|
+
const column = node.from - line.from;
|
|
2402
|
+
changes.push({
|
|
2403
|
+
from: node.from,
|
|
2404
|
+
to: node.from + mark2[0].length
|
|
2405
|
+
});
|
|
2406
|
+
while (line.to < node.to) {
|
|
2407
|
+
line = state.doc.lineAt(line.to + 1);
|
|
2408
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2409
|
+
if (open > column) {
|
|
2410
|
+
changes.push({
|
|
2411
|
+
from: line.from + column,
|
|
2412
|
+
to: line.from + Math.min(column + mark2[0].length, open)
|
|
2413
|
+
});
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
if (node.to >= to) {
|
|
2417
|
+
renumberListItems(node.node.nextSibling, 1, changes, state.doc);
|
|
2418
|
+
}
|
|
2419
|
+
return false;
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
if (!changes.length) {
|
|
2425
|
+
return false;
|
|
2426
|
+
}
|
|
2427
|
+
dispatch(state.update({
|
|
2428
|
+
changes,
|
|
2429
|
+
userEvent: "format.list.remove",
|
|
2430
|
+
scrollIntoView: true
|
|
2431
|
+
}));
|
|
2432
|
+
return true;
|
|
2433
|
+
};
|
|
2434
|
+
var toggleList = (type) => (target) => {
|
|
2435
|
+
const formatting2 = getFormatting(target.state);
|
|
2436
|
+
const active = formatting2.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
|
|
2437
|
+
return (active ? removeList(type) : addList(type))(target);
|
|
2438
|
+
};
|
|
2439
|
+
var renumberListItems = (item, counter, changes, doc) => {
|
|
2440
|
+
for (; item; item = item.nextSibling) {
|
|
2441
|
+
if (item.name === "ListItem") {
|
|
2442
|
+
const number = /(\s*)(\d+)[.)]/.exec(doc.sliceString(item.from, item.from + 10));
|
|
2443
|
+
if (!number || +number[2] === counter) {
|
|
2444
|
+
break;
|
|
2445
|
+
}
|
|
2446
|
+
const size = number[1].length + number[2].length;
|
|
2447
|
+
const newNum = String(counter);
|
|
2448
|
+
changes.push({
|
|
2449
|
+
from: item.from + Math.max(0, size - newNum.length),
|
|
2450
|
+
to: item.from + size,
|
|
2451
|
+
insert: newNum
|
|
2452
|
+
});
|
|
2453
|
+
counter++;
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
};
|
|
2457
|
+
var setBlockquote = (enable) => ({ state, dispatch }) => {
|
|
2458
|
+
const lines = [];
|
|
2459
|
+
let lastBlock = -1;
|
|
2460
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2461
|
+
syntaxTree2(state).iterate({
|
|
2462
|
+
from,
|
|
2463
|
+
to,
|
|
2464
|
+
enter: (node) => {
|
|
2465
|
+
if (Object.hasOwn(Textblocks, node.name) || node.name === "Table") {
|
|
2466
|
+
if (node.from === lastBlock) {
|
|
2467
|
+
return false;
|
|
2468
|
+
}
|
|
2469
|
+
lastBlock = node.from;
|
|
2470
|
+
let line = state.doc.lineAt(node.from);
|
|
2471
|
+
if (line.number > 1) {
|
|
2472
|
+
const prevLine = state.doc.line(line.number - 1);
|
|
2473
|
+
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
2474
|
+
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
2475
|
+
lines.push(prevLine);
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
for (; ; ) {
|
|
2480
|
+
lines.push(line);
|
|
2481
|
+
if (line.to >= node.to) {
|
|
2482
|
+
break;
|
|
2483
|
+
}
|
|
2484
|
+
line = state.doc.line(line.number + 1);
|
|
2485
|
+
}
|
|
2486
|
+
if (!enable && line.number < state.doc.lines) {
|
|
2487
|
+
const nextLine = state.doc.line(line.number + 1);
|
|
2488
|
+
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
2489
|
+
lines.push(nextLine);
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
return false;
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
});
|
|
2496
|
+
}
|
|
2497
|
+
const changes = [];
|
|
2498
|
+
for (const line of lines) {
|
|
2499
|
+
if (enable) {
|
|
2500
|
+
changes.push({
|
|
2501
|
+
from: line.from,
|
|
2502
|
+
insert: /\S/.test(line.text) ? "> " : ">"
|
|
2503
|
+
});
|
|
2504
|
+
} else {
|
|
2505
|
+
const quote = /((?:[\s>\-+*]|\d+[.)])*?)> ?/.exec(line.text);
|
|
2506
|
+
if (quote) {
|
|
2507
|
+
changes.push({
|
|
2508
|
+
from: line.from + quote[1].length,
|
|
2509
|
+
to: line.from + quote[0].length
|
|
2510
|
+
});
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
if (!changes.length) {
|
|
2515
|
+
return false;
|
|
2516
|
+
}
|
|
2517
|
+
dispatch(state.update({
|
|
2518
|
+
changes,
|
|
2519
|
+
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
2520
|
+
scrollIntoView: true
|
|
2521
|
+
}));
|
|
2522
|
+
return true;
|
|
2523
|
+
};
|
|
2524
|
+
var addBlockquote = setBlockquote(true);
|
|
2525
|
+
var removeBlockquote = setBlockquote(false);
|
|
2526
|
+
var toggleBlockquote = (target) => {
|
|
2527
|
+
return (getFormatting(target.state).blockquote ? removeBlockquote : addBlockquote)(target);
|
|
2528
|
+
};
|
|
2529
|
+
var addCodeblock = (target) => {
|
|
2530
|
+
const { state, dispatch } = target;
|
|
2531
|
+
const { selection } = state;
|
|
2532
|
+
if (selection.ranges.length === 1 && selection.main.empty) {
|
|
2533
|
+
const { head } = selection.main;
|
|
2534
|
+
const line = state.doc.lineAt(head);
|
|
2535
|
+
if (!/\S/.test(line.text) && head === line.from) {
|
|
2536
|
+
snippets.codeblock(target, null, line.from, line.to);
|
|
2537
|
+
return true;
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
const ranges = [];
|
|
2541
|
+
for (const { from, to } of selection.ranges) {
|
|
2542
|
+
let blockFrom = from;
|
|
2543
|
+
let blockTo = to;
|
|
2544
|
+
syntaxTree2(state).iterate({
|
|
2545
|
+
from,
|
|
2546
|
+
to,
|
|
2547
|
+
enter: (node) => {
|
|
2548
|
+
if (Object.hasOwn(Textblocks, node.name)) {
|
|
2549
|
+
if (from >= node.from && to <= node.to) {
|
|
2550
|
+
blockFrom = node.from;
|
|
2551
|
+
blockTo = node.to;
|
|
2552
|
+
} else {
|
|
2553
|
+
blockFrom = Math.min(blockFrom, state.doc.lineAt(node.from).from);
|
|
2554
|
+
blockTo = Math.max(blockTo, state.doc.lineAt(node.to).to);
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
});
|
|
2559
|
+
if (ranges.length && ranges[ranges.length - 1].to >= blockFrom - 1) {
|
|
2560
|
+
ranges[ranges.length - 1].to = blockTo;
|
|
2561
|
+
} else {
|
|
2562
|
+
ranges.push({
|
|
2563
|
+
from: blockFrom,
|
|
2564
|
+
to: blockTo
|
|
2565
|
+
});
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
if (!ranges.length) {
|
|
2569
|
+
return false;
|
|
2570
|
+
}
|
|
2571
|
+
const changes = ranges.map(({ from, to }) => {
|
|
2572
|
+
const column = from - state.doc.lineAt(from).from;
|
|
2573
|
+
return [
|
|
2574
|
+
{
|
|
2575
|
+
from,
|
|
2576
|
+
insert: "```\n" + " ".repeat(column)
|
|
2577
|
+
},
|
|
2578
|
+
{
|
|
2579
|
+
from: to,
|
|
2580
|
+
insert: "\n" + " ".repeat(column) + "```"
|
|
2581
|
+
}
|
|
2582
|
+
];
|
|
2583
|
+
});
|
|
2584
|
+
dispatch(state.update({
|
|
2585
|
+
changes,
|
|
2586
|
+
userEvent: "format.codeblock.add",
|
|
2587
|
+
scrollIntoView: true
|
|
2588
|
+
}));
|
|
2589
|
+
return true;
|
|
2590
|
+
};
|
|
2591
|
+
var removeCodeblock = ({ state, dispatch }) => {
|
|
2592
|
+
const changes = [];
|
|
2593
|
+
let lastBlock = -1;
|
|
2594
|
+
for (const { from, to } of state.selection.ranges) {
|
|
2595
|
+
syntaxTree2(state).iterate({
|
|
2596
|
+
from,
|
|
2597
|
+
to,
|
|
2598
|
+
enter: (node) => {
|
|
2599
|
+
if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
|
|
2600
|
+
lastBlock = node.from;
|
|
2601
|
+
const firstLine = state.doc.lineAt(node.from);
|
|
2602
|
+
if (node.name === "FencedCode") {
|
|
2603
|
+
changes.push({
|
|
2604
|
+
from: node.from,
|
|
2605
|
+
to: firstLine.to + 1 + node.from - firstLine.from
|
|
2606
|
+
});
|
|
2607
|
+
const lastLine = state.doc.lineAt(node.to);
|
|
2608
|
+
if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
|
|
2609
|
+
changes.push({
|
|
2610
|
+
from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
|
|
2611
|
+
to: lastLine.to
|
|
2612
|
+
});
|
|
2613
|
+
}
|
|
2614
|
+
} else {
|
|
2615
|
+
const column = node.from - firstLine.from;
|
|
2616
|
+
for (let line = firstLine; ; line = state.doc.line(line.number + 1)) {
|
|
2617
|
+
changes.push({
|
|
2618
|
+
from: line.from + column - 4,
|
|
2619
|
+
to: line.from + column
|
|
2620
|
+
});
|
|
2621
|
+
if (line.to >= node.to) {
|
|
2622
|
+
break;
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
});
|
|
2629
|
+
}
|
|
2630
|
+
if (!changes.length) {
|
|
2631
|
+
return false;
|
|
2632
|
+
}
|
|
2633
|
+
dispatch(state.update({
|
|
2634
|
+
changes,
|
|
2635
|
+
userEvent: "format.codeblock.remove",
|
|
2636
|
+
scrollIntoView: true
|
|
2637
|
+
}));
|
|
2638
|
+
return true;
|
|
2639
|
+
};
|
|
2640
|
+
var toggleCodeblock = (target) => {
|
|
2641
|
+
return (getFormatting(target.state).blockType === "codeblock" ? removeCodeblock : addCodeblock)(target);
|
|
1893
2642
|
};
|
|
1894
2643
|
var formatting = (options = {}) => {
|
|
1895
2644
|
return [
|
|
1896
2645
|
keymap5.of([
|
|
1897
2646
|
{
|
|
1898
2647
|
key: "meta-b",
|
|
1899
|
-
run:
|
|
2648
|
+
run: toggleStrong
|
|
1900
2649
|
}
|
|
1901
2650
|
]),
|
|
1902
2651
|
styling()
|
|
@@ -1950,6 +2699,206 @@ var styling = () => {
|
|
|
1950
2699
|
})
|
|
1951
2700
|
];
|
|
1952
2701
|
};
|
|
2702
|
+
var InlineMarker = {
|
|
2703
|
+
Emphasis: 1,
|
|
2704
|
+
StrongEmphasis: 0,
|
|
2705
|
+
InlineCode: 3,
|
|
2706
|
+
Strikethrough: 2
|
|
2707
|
+
};
|
|
2708
|
+
var IgnoreInline = /* @__PURE__ */ new Set([
|
|
2709
|
+
"Hardbreak",
|
|
2710
|
+
"HTMLTag",
|
|
2711
|
+
"Comment",
|
|
2712
|
+
"ProcessingInstruction",
|
|
2713
|
+
"Autolink",
|
|
2714
|
+
"HeaderMark",
|
|
2715
|
+
"QuoteMark",
|
|
2716
|
+
"ListMark",
|
|
2717
|
+
"LinkMark",
|
|
2718
|
+
"EmphasisMark",
|
|
2719
|
+
"CodeMark",
|
|
2720
|
+
"CodeText",
|
|
2721
|
+
"StrikethroughMark",
|
|
2722
|
+
"TaskMarker",
|
|
2723
|
+
"SuperscriptMark",
|
|
2724
|
+
"SubscriptMark"
|
|
2725
|
+
]);
|
|
2726
|
+
var Textblocks = {
|
|
2727
|
+
Paragraph: "paragraph",
|
|
2728
|
+
Task: "paragraph",
|
|
2729
|
+
CodeBlock: "codeblock",
|
|
2730
|
+
FencedCode: "codeblock",
|
|
2731
|
+
ATXHeading1: "heading1",
|
|
2732
|
+
ATXHeading2: "heading2",
|
|
2733
|
+
ATXHeading3: "heading3",
|
|
2734
|
+
ATXHeading4: "heading4",
|
|
2735
|
+
ATXHeading5: "heading5",
|
|
2736
|
+
ATXHeading6: "heading6",
|
|
2737
|
+
SetextHeading1: "heading1",
|
|
2738
|
+
SetextHeading2: "heading2",
|
|
2739
|
+
TableCell: "tablecell"
|
|
2740
|
+
};
|
|
2741
|
+
var getFormatting = (state) => {
|
|
2742
|
+
let blockType = null;
|
|
2743
|
+
const inline = [
|
|
2744
|
+
null,
|
|
2745
|
+
null,
|
|
2746
|
+
null,
|
|
2747
|
+
null
|
|
2748
|
+
];
|
|
2749
|
+
let link2 = false;
|
|
2750
|
+
let blockquote2 = null;
|
|
2751
|
+
let listStyle = null;
|
|
2752
|
+
const stack = [];
|
|
2753
|
+
let currentBlock = null;
|
|
2754
|
+
const advanceInline = (upto) => {
|
|
2755
|
+
if (!currentBlock) {
|
|
2756
|
+
return;
|
|
2757
|
+
}
|
|
2758
|
+
upto = Math.min(upto, currentBlock.end);
|
|
2759
|
+
if (upto <= currentBlock.pos) {
|
|
2760
|
+
return;
|
|
2761
|
+
}
|
|
2762
|
+
for (let i = 0; i < currentBlock.active.length; i++) {
|
|
2763
|
+
if (inline[i] === false) {
|
|
2764
|
+
continue;
|
|
2765
|
+
} else if (currentBlock.active[i]) {
|
|
2766
|
+
inline[i] = true;
|
|
2767
|
+
} else if (/\S/.test(state.doc.sliceString(currentBlock.pos, upto))) {
|
|
2768
|
+
inline[i] = false;
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
currentBlock.pos = upto;
|
|
2772
|
+
};
|
|
2773
|
+
const skipInline = (upto) => {
|
|
2774
|
+
if (currentBlock && upto > currentBlock.pos) {
|
|
2775
|
+
currentBlock.pos = Math.min(upto, currentBlock.end);
|
|
2776
|
+
}
|
|
2777
|
+
};
|
|
2778
|
+
const { selection } = state;
|
|
2779
|
+
for (const range of selection.ranges) {
|
|
2780
|
+
if (range.empty && inline.some((v) => v === null)) {
|
|
2781
|
+
const contextSize = Math.min(range.head, 6);
|
|
2782
|
+
const contextBefore = state.doc.sliceString(range.head - contextSize, range.head);
|
|
2783
|
+
let contextAfter = state.doc.sliceString(range.head, range.head + contextSize);
|
|
2784
|
+
for (let i = 0; i < contextSize; i++) {
|
|
2785
|
+
const ch = contextAfter[i];
|
|
2786
|
+
if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
|
|
2787
|
+
contextAfter = contextAfter.slice(0, i);
|
|
2788
|
+
break;
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
for (let i = 0; i < inline.length; i++) {
|
|
2792
|
+
const mark2 = inlineMarkerText(i);
|
|
2793
|
+
const found = contextAfter.indexOf(mark2);
|
|
2794
|
+
if (found > -1) {
|
|
2795
|
+
contextAfter = contextAfter.slice(0, found) + contextAfter.slice(found + mark2.length);
|
|
2796
|
+
if (inline[i] === null) {
|
|
2797
|
+
inline[i] = true;
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
syntaxTree2(state).iterate({
|
|
2803
|
+
from: range.from,
|
|
2804
|
+
to: range.to,
|
|
2805
|
+
enter: (node) => {
|
|
2806
|
+
advanceInline(node.from);
|
|
2807
|
+
const { name } = node;
|
|
2808
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2809
|
+
stack.push(name);
|
|
2810
|
+
} else if (name === "Link") {
|
|
2811
|
+
link2 = true;
|
|
2812
|
+
} else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {
|
|
2813
|
+
if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
2814
|
+
stack[stack.length - 1] = "TaskList";
|
|
2815
|
+
}
|
|
2816
|
+
const blockCode = Textblocks[name];
|
|
2817
|
+
if (blockType === null) {
|
|
2818
|
+
blockType = blockCode;
|
|
2819
|
+
} else if (blockType !== blockCode) {
|
|
2820
|
+
blockType = false;
|
|
2821
|
+
}
|
|
2822
|
+
if (blockCode !== "codeblock" && inline.some((i) => i !== false)) {
|
|
2823
|
+
currentBlock = {
|
|
2824
|
+
pos: Math.max(range.from, node.from),
|
|
2825
|
+
end: Math.min(range.to, node.to),
|
|
2826
|
+
active: [
|
|
2827
|
+
false,
|
|
2828
|
+
false,
|
|
2829
|
+
false,
|
|
2830
|
+
false
|
|
2831
|
+
]
|
|
2832
|
+
};
|
|
2833
|
+
}
|
|
2834
|
+
} else if (Object.hasOwn(InlineMarker, name) && currentBlock) {
|
|
2835
|
+
const index = InlineMarker[name];
|
|
2836
|
+
if (range.empty && inline[index] === null) {
|
|
2837
|
+
inline[index] = true;
|
|
2838
|
+
}
|
|
2839
|
+
currentBlock.active[index] = true;
|
|
2840
|
+
} else if (IgnoreInline.has(name)) {
|
|
2841
|
+
skipInline(node.to);
|
|
2842
|
+
}
|
|
2843
|
+
},
|
|
2844
|
+
leave: (node) => {
|
|
2845
|
+
advanceInline(node.to);
|
|
2846
|
+
const { name } = node;
|
|
2847
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2848
|
+
stack.pop();
|
|
2849
|
+
} else if (Object.hasOwn(Textblocks, name)) {
|
|
2850
|
+
let hasList = false;
|
|
2851
|
+
let hasQuote = false;
|
|
2852
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
2853
|
+
if (stack[i] === "Blockquote") {
|
|
2854
|
+
hasQuote = true;
|
|
2855
|
+
} else if (!hasList) {
|
|
2856
|
+
hasList = stack[i] === "TaskList" ? "task" : stack[i] === "BulletList" ? "bullet" : "ordered";
|
|
2857
|
+
}
|
|
2858
|
+
}
|
|
2859
|
+
if (blockquote2 === null) {
|
|
2860
|
+
blockquote2 = hasQuote;
|
|
2861
|
+
} else if (!hasQuote && blockquote2) {
|
|
2862
|
+
blockquote2 = false;
|
|
2863
|
+
}
|
|
2864
|
+
if (listStyle === null) {
|
|
2865
|
+
listStyle = hasList;
|
|
2866
|
+
} else if (listStyle !== hasList) {
|
|
2867
|
+
listStyle = false;
|
|
2868
|
+
}
|
|
2869
|
+
currentBlock = null;
|
|
2870
|
+
} else if (Object.hasOwn(InlineMarker, name) && currentBlock) {
|
|
2871
|
+
currentBlock.active[InlineMarker[name]] = false;
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
});
|
|
2875
|
+
}
|
|
2876
|
+
return {
|
|
2877
|
+
blockType: blockType || null,
|
|
2878
|
+
strong: inline[0] ?? false,
|
|
2879
|
+
emphasis: inline[1] ?? false,
|
|
2880
|
+
code: inline[3] ?? false,
|
|
2881
|
+
strikethrough: inline[2] ?? false,
|
|
2882
|
+
link: link2,
|
|
2883
|
+
blockquote: blockquote2 ?? false,
|
|
2884
|
+
listStyle: listStyle || null
|
|
2885
|
+
};
|
|
2886
|
+
};
|
|
2887
|
+
var useFormattingState = () => {
|
|
2888
|
+
const [state, setState] = useState(null);
|
|
2889
|
+
const observer = useMemo(() => EditorView9.updateListener.of((update2) => {
|
|
2890
|
+
if (update2.docChanged || update2.selectionSet) {
|
|
2891
|
+
const newState = getFormatting(update2.state);
|
|
2892
|
+
if (!state || !compareFormatting(state, newState)) {
|
|
2893
|
+
setState(newState);
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
}), []);
|
|
2897
|
+
return [
|
|
2898
|
+
state,
|
|
2899
|
+
observer
|
|
2900
|
+
];
|
|
2901
|
+
};
|
|
1953
2902
|
|
|
1954
2903
|
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
1955
2904
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
@@ -2002,8 +2951,8 @@ var heading2 = () => {
|
|
|
2002
2951
|
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
2003
2952
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
2004
2953
|
import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
|
|
2005
|
-
import { Decoration as Decoration6, EditorView as
|
|
2006
|
-
var styles4 =
|
|
2954
|
+
import { Decoration as Decoration6, EditorView as EditorView10, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
2955
|
+
var styles4 = EditorView10.baseTheme({
|
|
2007
2956
|
"& .cm-hr": {
|
|
2008
2957
|
// Note that block-level decorations should not have vertical margins,
|
|
2009
2958
|
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
@@ -2057,7 +3006,7 @@ var hr = () => {
|
|
|
2057
3006
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
2058
3007
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
2059
3008
|
import { StateField as StateField3 } from "@codemirror/state";
|
|
2060
|
-
import { Decoration as Decoration7, EditorView as
|
|
3009
|
+
import { Decoration as Decoration7, EditorView as EditorView11, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
2061
3010
|
var image = (options = {}) => {
|
|
2062
3011
|
return StateField3.define({
|
|
2063
3012
|
create: (state) => {
|
|
@@ -2084,7 +3033,7 @@ var image = (options = {}) => {
|
|
|
2084
3033
|
add: buildDecorations4(from, to, tr.state)
|
|
2085
3034
|
});
|
|
2086
3035
|
},
|
|
2087
|
-
provide: (field) =>
|
|
3036
|
+
provide: (field) => EditorView11.decorations.from(field)
|
|
2088
3037
|
});
|
|
2089
3038
|
};
|
|
2090
3039
|
var buildDecorations4 = (from, to, state) => {
|
|
@@ -2266,12 +3215,12 @@ var buildDecorations5 = (view, options) => {
|
|
|
2266
3215
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
2267
3216
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
2268
3217
|
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField4 } from "@codemirror/state";
|
|
2269
|
-
import { Decoration as Decoration9, EditorView as
|
|
3218
|
+
import { Decoration as Decoration9, EditorView as EditorView12, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
2270
3219
|
var table = (options = {}) => {
|
|
2271
3220
|
return StateField4.define({
|
|
2272
3221
|
create: (state) => update(state, options),
|
|
2273
3222
|
update: (_, tr) => update(tr.state, options),
|
|
2274
|
-
provide: (field) =>
|
|
3223
|
+
provide: (field) => EditorView12.decorations.from(field)
|
|
2275
3224
|
});
|
|
2276
3225
|
};
|
|
2277
3226
|
var update = (state, options) => {
|
|
@@ -2364,8 +3313,8 @@ var TableWidget = class extends WidgetType6 {
|
|
|
2364
3313
|
// packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
|
|
2365
3314
|
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
2366
3315
|
import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
|
|
2367
|
-
import { EditorView as
|
|
2368
|
-
var styles5 =
|
|
3316
|
+
import { EditorView as EditorView13, Decoration as Decoration10, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
|
|
3317
|
+
var styles5 = EditorView13.baseTheme({
|
|
2369
3318
|
"& .cm-task": {
|
|
2370
3319
|
color: getToken("extend.colors.blue.500")
|
|
2371
3320
|
},
|
|
@@ -2590,11 +3539,11 @@ var defaultTheme = {
|
|
|
2590
3539
|
fontSize: "16px"
|
|
2591
3540
|
},
|
|
2592
3541
|
"&light .cm-content": {
|
|
2593
|
-
color: get3(tokens, "extend.
|
|
3542
|
+
color: get3(tokens, "extend.semanticColors.base.fg.light", "black"),
|
|
2594
3543
|
caretColor: "black"
|
|
2595
3544
|
},
|
|
2596
3545
|
"&dark .cm-content": {
|
|
2597
|
-
color: get3(tokens, "extend.
|
|
3546
|
+
color: get3(tokens, "extend.semanticColors.base.fg.dark", "white"),
|
|
2598
3547
|
caretColor: "white"
|
|
2599
3548
|
},
|
|
2600
3549
|
//
|
|
@@ -2606,8 +3555,11 @@ var defaultTheme = {
|
|
|
2606
3555
|
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
2607
3556
|
borderLeft: "2px solid white"
|
|
2608
3557
|
},
|
|
2609
|
-
".cm-placeholder": {
|
|
2610
|
-
|
|
3558
|
+
"&light .cm-placeholder": {
|
|
3559
|
+
color: get3(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
3560
|
+
},
|
|
3561
|
+
"&dark .cm-placeholder": {
|
|
3562
|
+
color: get3(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
2611
3563
|
},
|
|
2612
3564
|
//
|
|
2613
3565
|
// line
|
|
@@ -2795,7 +3747,7 @@ var EditorModes = [
|
|
|
2795
3747
|
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, editorMode, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
2796
3748
|
const { themeMode } = useThemeContext();
|
|
2797
3749
|
const rootRef = useRef(null);
|
|
2798
|
-
const [view, setView] =
|
|
3750
|
+
const [view, setView] = useState2(null);
|
|
2799
3751
|
useImperativeHandle(forwardedRef, () => view, [
|
|
2800
3752
|
view
|
|
2801
3753
|
]);
|
|
@@ -2824,7 +3776,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2824
3776
|
selection,
|
|
2825
3777
|
extensions: [
|
|
2826
3778
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
2827
|
-
|
|
3779
|
+
EditorView14.exceptionSink.of((err) => {
|
|
2828
3780
|
log2.catch(err, void 0, {
|
|
2829
3781
|
F: __dxlog_file3,
|
|
2830
3782
|
L: 134,
|
|
@@ -2834,17 +3786,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2834
3786
|
}),
|
|
2835
3787
|
// Theme.
|
|
2836
3788
|
// TODO(burdon): Make configurable.
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
3789
|
+
EditorView14.baseTheme(defaultTheme),
|
|
3790
|
+
EditorView14.theme(theme ?? {}),
|
|
3791
|
+
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3792
|
+
EditorView14.editorAttributes.of({
|
|
2841
3793
|
class: slots.editor?.className ?? ""
|
|
2842
3794
|
}),
|
|
2843
|
-
|
|
3795
|
+
EditorView14.contentAttributes.of({
|
|
2844
3796
|
class: slots.content?.className ?? ""
|
|
2845
3797
|
}),
|
|
2846
3798
|
// State.
|
|
2847
|
-
|
|
3799
|
+
EditorView14.editable.of(!readonly),
|
|
2848
3800
|
EditorState2.readOnly.of(!!readonly),
|
|
2849
3801
|
// Storage and replication.
|
|
2850
3802
|
// NOTE: This must come before user extensions.
|
|
@@ -2855,7 +3807,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
2855
3807
|
...extensions
|
|
2856
3808
|
].filter(isNotFalsy3)
|
|
2857
3809
|
});
|
|
2858
|
-
const newView = new
|
|
3810
|
+
const newView = new EditorView14({
|
|
2859
3811
|
state,
|
|
2860
3812
|
parent: rootRef.current,
|
|
2861
3813
|
scrollTo,
|
|
@@ -2948,11 +3900,10 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
|
|
|
2948
3900
|
});
|
|
2949
3901
|
var defaultSlots = {
|
|
2950
3902
|
root: {
|
|
2951
|
-
|
|
2952
|
-
className: mx3("flex flex-col grow overflow-y-auto", attentionSurface)
|
|
3903
|
+
className: mx3("grow", focusRing)
|
|
2953
3904
|
},
|
|
2954
3905
|
editor: {
|
|
2955
|
-
className: "
|
|
3906
|
+
className: "bs-full"
|
|
2956
3907
|
}
|
|
2957
3908
|
};
|
|
2958
3909
|
var defaultTextSlots = {
|
|
@@ -2963,35 +3914,40 @@ var defaultMarkdownSlots = {
|
|
|
2963
3914
|
};
|
|
2964
3915
|
|
|
2965
3916
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
2966
|
-
import {
|
|
3917
|
+
import { CaretRight, ChatText, Code, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextItalic } from "@phosphor-icons/react";
|
|
2967
3918
|
import { createContext } from "@radix-ui/react-context";
|
|
2968
3919
|
import React2 from "react";
|
|
2969
3920
|
import { Button, DensityProvider, Select } from "@dxos/react-ui";
|
|
2970
|
-
import { getSize } from "@dxos/react-ui-theme";
|
|
3921
|
+
import { getSize, mx as mx4 } from "@dxos/react-ui-theme";
|
|
2971
3922
|
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
2972
|
-
var ToolbarRoot = ({ children, onAction }) => {
|
|
3923
|
+
var ToolbarRoot = ({ children, onAction, state }) => {
|
|
2973
3924
|
return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
|
|
2974
|
-
onAction
|
|
3925
|
+
onAction,
|
|
3926
|
+
state
|
|
2975
3927
|
}, /* @__PURE__ */ React2.createElement(DensityProvider, {
|
|
2976
3928
|
density: "fine"
|
|
2977
3929
|
}, /* @__PURE__ */ React2.createElement("div", {
|
|
2978
3930
|
role: "toolbar",
|
|
2979
|
-
className: "flex w-full shrink-0 p-
|
|
3931
|
+
className: "flex w-full shrink-0 p-1 gap-2 items-center whitespace-nowrap overflow-hidden"
|
|
2980
3932
|
}, children)));
|
|
2981
3933
|
};
|
|
2982
|
-
var ToolbarButton = ({ Icon, onClick, title }) => {
|
|
2983
|
-
const { onAction } = useToolbarContext("ToolbarButton");
|
|
2984
|
-
const
|
|
2985
|
-
|
|
3934
|
+
var ToolbarButton = ({ Icon, onClick, title, getState, disable }) => {
|
|
3935
|
+
const { onAction, state } = useToolbarContext("ToolbarButton");
|
|
3936
|
+
const active = getState && state ? getState(state) : false;
|
|
3937
|
+
const disabled = disable && state ? disable(state) : false;
|
|
3938
|
+
const handleClick = (event) => {
|
|
3939
|
+
const action = onClick(state);
|
|
2986
3940
|
if (action) {
|
|
2987
3941
|
onAction?.(action);
|
|
3942
|
+
event.preventDefault();
|
|
2988
3943
|
}
|
|
2989
3944
|
};
|
|
2990
3945
|
return /* @__PURE__ */ React2.createElement(Button, {
|
|
2991
3946
|
variant: "ghost",
|
|
2992
|
-
classNames: "p-2",
|
|
2993
|
-
|
|
2994
|
-
title
|
|
3947
|
+
classNames: mx4("p-2", active && "ring-[1px]"),
|
|
3948
|
+
onMouseDown: handleClick,
|
|
3949
|
+
title,
|
|
3950
|
+
disabled
|
|
2995
3951
|
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
2996
3952
|
className: getSize(5)
|
|
2997
3953
|
}));
|
|
@@ -3000,16 +3956,20 @@ var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
|
3000
3956
|
className: "grow"
|
|
3001
3957
|
});
|
|
3002
3958
|
var MarkdownHeading = () => {
|
|
3003
|
-
const { onAction } = useToolbarContext("MarkdownFormatting");
|
|
3959
|
+
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
|
3960
|
+
const blockType = state ? state.blockType : "paragraph";
|
|
3961
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
|
3962
|
+
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : null;
|
|
3004
3963
|
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
3005
|
-
|
|
3006
|
-
|
|
3964
|
+
disabled: value === null,
|
|
3965
|
+
value: value ?? "0",
|
|
3966
|
+
onValueChange: (value2) => onAction?.({
|
|
3007
3967
|
type: "heading",
|
|
3008
|
-
data: parseInt(
|
|
3968
|
+
data: parseInt(value2)
|
|
3009
3969
|
})
|
|
3010
|
-
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
3011
|
-
|
|
3012
|
-
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3970
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, null, /* @__PURE__ */ React2.createElement(Paragraph, {
|
|
3971
|
+
className: getSize(5)
|
|
3972
|
+
})), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
3013
3973
|
value: "0"
|
|
3014
3974
|
}, "Paragraph"), [
|
|
3015
3975
|
1,
|
|
@@ -3027,21 +3987,39 @@ var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
|
|
|
3027
3987
|
role: "none"
|
|
3028
3988
|
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3029
3989
|
Icon: TextB,
|
|
3030
|
-
title: "
|
|
3031
|
-
|
|
3032
|
-
|
|
3990
|
+
title: "String",
|
|
3991
|
+
disable: (s) => s.blockType === "codeblock",
|
|
3992
|
+
getState: (s) => s.strong,
|
|
3993
|
+
onClick: (s) => ({
|
|
3994
|
+
type: "strong",
|
|
3995
|
+
data: s ? !s.strong : null
|
|
3033
3996
|
})
|
|
3034
3997
|
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3035
3998
|
Icon: TextItalic,
|
|
3036
|
-
title: "
|
|
3037
|
-
|
|
3038
|
-
|
|
3999
|
+
title: "Emphasis",
|
|
4000
|
+
disable: (s) => s.blockType === "codeblock",
|
|
4001
|
+
getState: (s) => s.emphasis,
|
|
4002
|
+
onClick: (s) => ({
|
|
4003
|
+
type: "emphasis",
|
|
4004
|
+
data: s ? !s.emphasis : null
|
|
3039
4005
|
})
|
|
3040
4006
|
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3041
4007
|
Icon: TextStrikethrough,
|
|
3042
4008
|
title: "Strike-through",
|
|
3043
|
-
|
|
3044
|
-
|
|
4009
|
+
disable: (s) => s.blockType === "codeblock",
|
|
4010
|
+
getState: (s) => s.strikethrough,
|
|
4011
|
+
onClick: (s) => ({
|
|
4012
|
+
type: "strikethrough",
|
|
4013
|
+
data: s ? !s.strikethrough : null
|
|
4014
|
+
})
|
|
4015
|
+
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4016
|
+
Icon: Code,
|
|
4017
|
+
title: "Inline code",
|
|
4018
|
+
disable: (s) => s.blockType === "codeblock",
|
|
4019
|
+
getState: (s) => s.code,
|
|
4020
|
+
onClick: (s) => ({
|
|
4021
|
+
type: "code",
|
|
4022
|
+
data: s ? !s.code : null
|
|
3045
4023
|
})
|
|
3046
4024
|
}));
|
|
3047
4025
|
var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
|
|
@@ -3049,35 +4027,45 @@ var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
|
|
|
3049
4027
|
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3050
4028
|
Icon: ListBullets,
|
|
3051
4029
|
title: "Bullet list",
|
|
3052
|
-
|
|
3053
|
-
|
|
4030
|
+
getState: (s) => s.listStyle === "bullet",
|
|
4031
|
+
onClick: (s) => ({
|
|
4032
|
+
type: "list-bullet",
|
|
4033
|
+
data: s ? s.listStyle !== "bullet" : null
|
|
3054
4034
|
})
|
|
3055
4035
|
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3056
4036
|
Icon: ListNumbers,
|
|
3057
4037
|
title: "Numbered list",
|
|
3058
|
-
|
|
3059
|
-
|
|
4038
|
+
getState: (s) => s.listStyle === "ordered",
|
|
4039
|
+
onClick: (s) => ({
|
|
4040
|
+
type: "list-ordered",
|
|
4041
|
+
data: s ? s.listStyle !== "ordered" : null
|
|
3060
4042
|
})
|
|
3061
4043
|
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3062
4044
|
Icon: ListChecks,
|
|
3063
4045
|
title: "Task list",
|
|
3064
|
-
|
|
3065
|
-
|
|
4046
|
+
getState: (s) => s.listStyle === "task",
|
|
4047
|
+
onClick: (s) => ({
|
|
4048
|
+
type: "list-tasks",
|
|
4049
|
+
data: s ? s.listStyle !== "task" : null
|
|
3066
4050
|
})
|
|
3067
4051
|
}));
|
|
3068
4052
|
var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
3069
4053
|
role: "none"
|
|
3070
4054
|
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3071
4055
|
Icon: CaretRight,
|
|
3072
|
-
title: "Block
|
|
3073
|
-
|
|
3074
|
-
|
|
4056
|
+
title: "Block quote",
|
|
4057
|
+
getState: (s) => s.blockquote,
|
|
4058
|
+
onClick: (s) => ({
|
|
4059
|
+
type: "blockquote",
|
|
4060
|
+
data: s ? !s.blockquote : null
|
|
3075
4061
|
})
|
|
3076
4062
|
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3077
4063
|
Icon: Code,
|
|
3078
4064
|
title: "Code block",
|
|
3079
|
-
|
|
3080
|
-
|
|
4065
|
+
getState: (s) => s.blockType === "codeblock",
|
|
4066
|
+
onClick: (s) => ({
|
|
4067
|
+
type: "codeblock",
|
|
4068
|
+
data: s ? s.blockType !== "codeblock" : null
|
|
3081
4069
|
})
|
|
3082
4070
|
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3083
4071
|
Icon: Table2,
|
|
@@ -3091,20 +4079,10 @@ var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
|
|
|
3091
4079
|
}, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3092
4080
|
Icon: Link,
|
|
3093
4081
|
title: "Link",
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
Icon: At,
|
|
3099
|
-
title: "Mention",
|
|
3100
|
-
onClick: () => ({
|
|
3101
|
-
type: "mention"
|
|
3102
|
-
})
|
|
3103
|
-
}), /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
3104
|
-
Icon: Image,
|
|
3105
|
-
title: "Image",
|
|
3106
|
-
onClick: () => ({
|
|
3107
|
-
type: "image"
|
|
4082
|
+
getState: (s) => s.link,
|
|
4083
|
+
onClick: (s) => ({
|
|
4084
|
+
type: "link",
|
|
4085
|
+
data: s ? !s.link : null
|
|
3108
4086
|
})
|
|
3109
4087
|
}));
|
|
3110
4088
|
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), /* @__PURE__ */ React2.createElement(MarkdownLinks, null));
|
|
@@ -3240,45 +4218,52 @@ var useActionHandler = (view) => {
|
|
|
3240
4218
|
if (!view) {
|
|
3241
4219
|
return;
|
|
3242
4220
|
}
|
|
4221
|
+
let inlineType, listType;
|
|
3243
4222
|
switch (action.type) {
|
|
3244
4223
|
case "heading":
|
|
3245
4224
|
setHeading(parseInt(action.data))(view);
|
|
3246
4225
|
break;
|
|
3247
|
-
case "
|
|
3248
|
-
|
|
3249
|
-
break;
|
|
3250
|
-
case "italic":
|
|
3251
|
-
toggleItalic(view);
|
|
3252
|
-
break;
|
|
4226
|
+
case "strong":
|
|
4227
|
+
case "emphasis":
|
|
3253
4228
|
case "strikethrough":
|
|
3254
|
-
|
|
4229
|
+
case "code":
|
|
4230
|
+
inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
|
4231
|
+
(typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
|
|
3255
4232
|
break;
|
|
3256
|
-
case "list":
|
|
3257
|
-
|
|
4233
|
+
case "list-ordered":
|
|
4234
|
+
case "list-bullet":
|
|
4235
|
+
case "list-tasks":
|
|
4236
|
+
listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
|
|
4237
|
+
(action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
|
|
4238
|
+
break;
|
|
4239
|
+
case "blockquote":
|
|
4240
|
+
(action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
|
|
3258
4241
|
break;
|
|
3259
4242
|
case "codeblock":
|
|
3260
|
-
|
|
4243
|
+
(action.data === false ? removeCodeblock : addCodeblock)(view);
|
|
3261
4244
|
break;
|
|
3262
4245
|
case "table":
|
|
3263
4246
|
insertTable(view);
|
|
3264
4247
|
break;
|
|
4248
|
+
case "link":
|
|
4249
|
+
(action.data === false ? removeLink : addLink)(view);
|
|
4250
|
+
break;
|
|
3265
4251
|
case "comment":
|
|
3266
4252
|
createComment(view);
|
|
3267
4253
|
break;
|
|
3268
4254
|
}
|
|
3269
4255
|
setTimeout(() => {
|
|
3270
|
-
view.
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
});
|
|
4256
|
+
if (!view.hasFocus) {
|
|
4257
|
+
view.focus();
|
|
4258
|
+
}
|
|
3274
4259
|
});
|
|
3275
4260
|
};
|
|
3276
4261
|
};
|
|
3277
4262
|
|
|
3278
4263
|
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
3279
|
-
import { useState as
|
|
4264
|
+
import { useState as useState3 } from "react";
|
|
3280
4265
|
var useEditorView = () => {
|
|
3281
|
-
const [view, setView] =
|
|
4266
|
+
const [view, setView] = useState3(null);
|
|
3282
4267
|
return [
|
|
3283
4268
|
(ref) => {
|
|
3284
4269
|
setView(ref);
|
|
@@ -3288,15 +4273,15 @@ var useEditorView = () => {
|
|
|
3288
4273
|
};
|
|
3289
4274
|
|
|
3290
4275
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
3291
|
-
import { EditorSelection, EditorState as EditorState3 } from "@codemirror/state";
|
|
3292
|
-
import { EditorView as
|
|
3293
|
-
import { useEffect as useEffect3, useRef as useRef2, useState as
|
|
4276
|
+
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4277
|
+
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4278
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
|
|
3294
4279
|
import { log as log4 } from "@dxos/log";
|
|
3295
4280
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
3296
4281
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
3297
4282
|
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
|
|
3298
4283
|
const onUpdate = useRef2();
|
|
3299
|
-
const [view, setView] =
|
|
4284
|
+
const [view, setView] = useState4();
|
|
3300
4285
|
const parentRef = useRef2(null);
|
|
3301
4286
|
useEffect3(() => {
|
|
3302
4287
|
if (parentRef.current) {
|
|
@@ -3305,7 +4290,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
3305
4290
|
selection,
|
|
3306
4291
|
extensions: [
|
|
3307
4292
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3308
|
-
|
|
4293
|
+
EditorView15.exceptionSink.of((err) => {
|
|
3309
4294
|
log4.catch(err, void 0, {
|
|
3310
4295
|
F: __dxlog_file5,
|
|
3311
4296
|
L: 57,
|
|
@@ -3314,12 +4299,12 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
3314
4299
|
});
|
|
3315
4300
|
}),
|
|
3316
4301
|
extensions,
|
|
3317
|
-
|
|
4302
|
+
EditorView15.updateListener.of(() => {
|
|
3318
4303
|
onUpdate.current?.();
|
|
3319
4304
|
})
|
|
3320
4305
|
].filter(isNotFalsy4)
|
|
3321
4306
|
});
|
|
3322
|
-
const view2 = new
|
|
4307
|
+
const view2 = new EditorView15({
|
|
3323
4308
|
parent: parentRef.current,
|
|
3324
4309
|
scrollTo,
|
|
3325
4310
|
state,
|
|
@@ -3343,7 +4328,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
3343
4328
|
useEffect3(() => {
|
|
3344
4329
|
if (view) {
|
|
3345
4330
|
if (!selection && !view.state.selection.main.anchor) {
|
|
3346
|
-
selection =
|
|
4331
|
+
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
3347
4332
|
}
|
|
3348
4333
|
if (selection || scrollTo) {
|
|
3349
4334
|
onUpdate.current = () => {
|
|
@@ -3376,19 +4361,19 @@ var createDataExtensions = ({ readonly = false } = {}) => {
|
|
|
3376
4361
|
return [
|
|
3377
4362
|
//
|
|
3378
4363
|
EditorState3.readOnly.of(readonly),
|
|
3379
|
-
|
|
4364
|
+
EditorView15.editable.of(!readonly)
|
|
3380
4365
|
];
|
|
3381
4366
|
};
|
|
3382
4367
|
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
3383
4368
|
return [
|
|
3384
4369
|
//
|
|
3385
|
-
|
|
3386
|
-
theme &&
|
|
3387
|
-
|
|
3388
|
-
|
|
4370
|
+
EditorView15.baseTheme(defaultTheme),
|
|
4371
|
+
theme && EditorView15.theme(theme),
|
|
4372
|
+
EditorView15.darkTheme.of(themeMode === "dark"),
|
|
4373
|
+
EditorView15.editorAttributes.of({
|
|
3389
4374
|
class: slots?.editor?.className ?? ""
|
|
3390
4375
|
}),
|
|
3391
|
-
|
|
4376
|
+
EditorView15.contentAttributes.of({
|
|
3392
4377
|
class: slots?.content?.className ?? ""
|
|
3393
4378
|
})
|
|
3394
4379
|
].filter(isNotFalsy4);
|
|
@@ -3396,7 +4381,7 @@ var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
|
3396
4381
|
|
|
3397
4382
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
3398
4383
|
import get4 from "lodash.get";
|
|
3399
|
-
import { useEffect as useEffect4, useState as
|
|
4384
|
+
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
3400
4385
|
import { generateName } from "@dxos/display-name";
|
|
3401
4386
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
3402
4387
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
@@ -3404,7 +4389,7 @@ import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
|
3404
4389
|
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
3405
4390
|
var useTextModel = (props) => {
|
|
3406
4391
|
const { identity, space, text } = props;
|
|
3407
|
-
const [model, setModel] =
|
|
4392
|
+
const [model, setModel] = useState5();
|
|
3408
4393
|
useEffect4(() => setModel(createModel(props)), [
|
|
3409
4394
|
identity,
|
|
3410
4395
|
space,
|
|
@@ -3412,10 +4397,19 @@ var useTextModel = (props) => {
|
|
|
3412
4397
|
]);
|
|
3413
4398
|
return model;
|
|
3414
4399
|
};
|
|
4400
|
+
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4401
|
+
const [content, setContent] = useState5(defaultContent ?? "");
|
|
4402
|
+
return {
|
|
4403
|
+
id,
|
|
4404
|
+
content,
|
|
4405
|
+
setContent,
|
|
4406
|
+
text: () => content
|
|
4407
|
+
};
|
|
4408
|
+
};
|
|
3415
4409
|
var createModel = ({ space, identity, text }) => {
|
|
3416
4410
|
invariant3(isAutomergeObject(text), void 0, {
|
|
3417
4411
|
F: __dxlog_file6,
|
|
3418
|
-
L:
|
|
4412
|
+
L: 50,
|
|
3419
4413
|
S: void 0,
|
|
3420
4414
|
A: [
|
|
3421
4415
|
"isAutomergeObject(text)",
|
|
@@ -3464,6 +4458,8 @@ export {
|
|
|
3464
4458
|
Cursor,
|
|
3465
4459
|
Doc,
|
|
3466
4460
|
EditorModes,
|
|
4461
|
+
Inline,
|
|
4462
|
+
List,
|
|
3467
4463
|
MarkdownEditor,
|
|
3468
4464
|
RemoteSelectionsDecorator,
|
|
3469
4465
|
SpaceAwarenessProvider,
|
|
@@ -3472,6 +4468,11 @@ export {
|
|
|
3472
4468
|
Toolbar,
|
|
3473
4469
|
YText,
|
|
3474
4470
|
YXmlFragment,
|
|
4471
|
+
addBlockquote,
|
|
4472
|
+
addCodeblock,
|
|
4473
|
+
addLink,
|
|
4474
|
+
addList,
|
|
4475
|
+
addStyle,
|
|
3475
4476
|
autocomplete,
|
|
3476
4477
|
automerge,
|
|
3477
4478
|
awareness,
|
|
@@ -3481,6 +4482,7 @@ export {
|
|
|
3481
4482
|
code2 as code,
|
|
3482
4483
|
codeTheme,
|
|
3483
4484
|
comments,
|
|
4485
|
+
compareFormatting,
|
|
3484
4486
|
createBasicBundle,
|
|
3485
4487
|
createComment,
|
|
3486
4488
|
createDataExtensions,
|
|
@@ -3493,12 +4495,13 @@ export {
|
|
|
3493
4495
|
defaultTheme,
|
|
3494
4496
|
focusComment,
|
|
3495
4497
|
formatting,
|
|
4498
|
+
getFormatting,
|
|
3496
4499
|
getToken,
|
|
3497
4500
|
heading2 as heading,
|
|
3498
4501
|
hr,
|
|
3499
4502
|
image,
|
|
3500
|
-
insertCodeblock,
|
|
3501
4503
|
insertTable,
|
|
4504
|
+
keymap7 as keymap,
|
|
3502
4505
|
link,
|
|
3503
4506
|
listener,
|
|
3504
4507
|
logChanges,
|
|
@@ -3509,22 +4512,34 @@ export {
|
|
|
3509
4512
|
mention,
|
|
3510
4513
|
modelState,
|
|
3511
4514
|
outliner,
|
|
4515
|
+
removeBlockquote,
|
|
4516
|
+
removeCodeblock,
|
|
4517
|
+
removeLink,
|
|
4518
|
+
removeList,
|
|
4519
|
+
removeStyle,
|
|
4520
|
+
setBlockquote,
|
|
3512
4521
|
setComments,
|
|
3513
4522
|
setHeading,
|
|
3514
4523
|
setSelection,
|
|
4524
|
+
setStyle,
|
|
3515
4525
|
table,
|
|
3516
4526
|
tags2 as tags,
|
|
3517
4527
|
tasklist,
|
|
3518
4528
|
textTheme,
|
|
3519
|
-
|
|
3520
|
-
|
|
4529
|
+
toggleBlockquote,
|
|
4530
|
+
toggleCodeblock,
|
|
4531
|
+
toggleEmphasis,
|
|
4532
|
+
toggleInlineCode,
|
|
3521
4533
|
toggleList,
|
|
3522
4534
|
toggleStrikethrough,
|
|
4535
|
+
toggleStrong,
|
|
3523
4536
|
toggleStyle,
|
|
3524
4537
|
typewriter,
|
|
3525
4538
|
useActionHandler,
|
|
3526
4539
|
useComments,
|
|
3527
4540
|
useEditorView,
|
|
4541
|
+
useFormattingState,
|
|
4542
|
+
useInMemoryTextModel,
|
|
3528
4543
|
useTextEditor,
|
|
3529
4544
|
useTextModel,
|
|
3530
4545
|
useToolbarContext
|